Method Expressions Use Case

912 views
Skip to first unread message

kevinc...@gmail.com

unread,
Sep 21, 2013, 5:16:25 PM9/21/13
to golan...@googlegroups.com
I'm trying to figure out where method expressions would be useful. I get that they are an advanced feature that I may find use for, but I would like to know how to use them properly.

Any examples in the wild of their use?

Jeff Hodges

unread,
Sep 21, 2013, 10:21:45 PM9/21/13
to golan...@googlegroups.com, kevinc...@gmail.com
One really nice way I've used them is to provide context to http.Handlers (a.k.a. dependency injection, a.k.a. "passing things into a struct") without having to write many ServeHTTP wrappers. Let me drop a concrete example:


I put all the things needed to satisfy certain types of requests together into one struct (the *sql.DB in this instance) and have many HTTP paths handled by different methods on it. This avoids having to create a http.Handler for each HTTP path or writing a bunch of globals that would be used in global functions.
 
In the wild, here's a commit I made to do this when method values were released (but using bmizerany/pat instead of net/http for the muxing, so there was no nice HandlerFunc equivalent): <https://github.com/jmhodges/plus2rss/commit/e257b2ca0dfc5f32ac15b4c35a368c27ec770ac9>.

Of course, overusing this pattern can cause your structs to become too broad and God-Object-like, but, used judiciously, it highlights what each request is doing by giving them a common theme while making the handling easier to test.

tedsta

unread,
Sep 21, 2013, 10:52:14 PM9/21/13
to golan...@googlegroups.com, kevinc...@gmail.com
I actually just searched for, found, and used these today as I was working on my game engine! I also use them to provide a context for callbacks.

Kevin Gillette

unread,
Sep 22, 2013, 8:51:22 AM9/22/13
to golan...@googlegroups.com

zephyr...@gmail.com

unread,
Sep 22, 2013, 10:04:08 AM9/22/13
to golan...@googlegroups.com, kevinc...@gmail.com

Steven Blenkinsop

unread,
Sep 22, 2013, 12:24:31 PM9/22/13
to tedsta, golan...@googlegroups.com, kevinc...@gmail.com
There seems to be some confusion about whether the op is talking about:



I'm not sure this is the best way distinguish the two concepts, btw, since both are expressions denoting function values derived in some way from methods. I'd call the second one a method *selector* expression. There is a distinction between method values derived from selector expressions and any other function value, though, since, iirc, method values cannot be uniquely identified by using `runtime.FuncForPC` on their `reflect.Value.Pointer`s.
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Steven Blenkinsop

unread,
Sep 22, 2013, 1:02:01 PM9/22/13
to tedsta, golan...@googlegroups.com, kevinc...@gmail.com
Haven't tested it, but it seems that the distinction I mentioned in the last paragraph only applies to method values generated by reflect:

kevinc...@gmail.com

unread,
Sep 23, 2013, 10:20:17 AM9/23/13
to golan...@googlegroups.com, tedsta, kevinc...@gmail.com
The original question was about method expressions, not method values. Thanks for the chance to clarify, I appreciate it.

Still haven't quite grokked where I would use them, but I'm sure that will come with time.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.

roger peppe

unread,
Sep 23, 2013, 12:22:13 PM9/23/13
to kevinc...@gmail.com, golang-nuts, tedsta
I've sometimes used them in places where I want to treat
several methods of an object in a uniform way.

For example:

var entryPoints = map[string] func(*MyType, string) error {
"foo": (*MyType).Foo,
"bar": (*MyType).Bar,
}

Another place I've used them is when I need to mock
a method. I'll do:

var myTypeFoo = (*MyType).Foo

and then call myTypeFoo(x) instead of x.Foo. In test code,
I can swap myTypeFoo for a function defined in the test
and interpose custom behaviour.
>>> email to golang-nuts...@googlegroups.com.
>>> For more options, visit https://groups.google.com/groups/opt_out.
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages