Intercepting field access and method call

101 views
Skip to first unread message

Tanmay Das

unread,
Apr 12, 2020, 2:59:08 AM4/12/20
to golang-nuts
Say you have a struct Foo and you access fields and call methods on it as you normally would. But is it possible to execute a hook before or after that field access or method call? A good scenario will be:

The user calls non-existent method foo.Bar() or accesses non-existent field foo.Bar. If they don't exist, I want to:
a) In case of a method call: forward that call to foo.Baz()
b) In case of field access: set the foo.Bar at runtime with some value

Kurtis Rader

unread,
Apr 12, 2020, 3:13:03 AM4/12/20
to Tanmay Das, golang-nuts
No, as far as I know. You're looking for a language like Python, which I love, but that isn't the Go model of behavior. This also seems like a http://xyproblem.info/ question. What is it you really want to do? Are you trying to mock something for a unit test?

--
Kurtis Rader
Caretaker of the exceptional canines Junior and Hank

Tanmay Das

unread,
Apr 12, 2020, 4:20:48 AM4/12/20
to golang-nuts
Hi, thanks for your reply. I am still in the learning phase and when I learn the usage of a new tool I try to keep notes of what's allowed and what's not allowed by that tool. That's all :) So at this moment, it's not possible for me to come up with a concrete production-level use case. But the behavior I described is very common in dynamic languages. If a field doesn't exist, create that field at runtime. If a method doesn't exist, make some decision on-the-fly, maybe call another method. In both cases, the caller knows that they (field and method) don't exist and expects that they will be created/responded accordingly at runtime instead of failing. In PHP they're known as Magic Methods. In JavaScript, they're called Proxies. I know that's too much dynamic behavior to ask from a statically typed language. But now I know that it's not allowed.

Nedim Sabic

unread,
Apr 12, 2020, 3:30:15 PM4/12/20
to Tanmay Das, golang-nuts
Hi,

You could achieve function / method interception with ebpf and uprobes. You can find a thorough tutorial here:  https://sematext.com/blog/ebpf-userland-apps/

--
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.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/4417bc0c-d521-4a3b-a8af-78c399238e80%40googlegroups.com.

Jake Montgomery

unread,
Apr 12, 2020, 4:10:13 PM4/12/20
to golang-nuts
It sounds like maybe this is your first statically typed language. Go is statically typed, which means that the scenarios you are talking about can not happen. That is by design, and has huge benefits for code reliability, and also readability. If you call a function that takes a Foo struct as a parameter, then it is impossible for that function to even try to access non-existent fields or members. That would be a  compile time error. So the 'problem' you are trying to solve is already solved, insofar as it can never occur.  (It might be, I suppose, possible to 'hack' such a case using unsafe, but you should never see or write such code.)

Working in a statically typed language takes some getting used to, and can feel restrictive at first. But I almost always prefer them for production level code. Remember simplicity, readability (which includes comprehensibility) and reliability are cornerstones of the Go language.

Good Luck, and enjoy learning Go.

Brian Candler

unread,
Apr 12, 2020, 4:23:12 PM4/12/20
to golang-nuts
And just to add, since you mentioned fields on a struct: all fields are initialized to their "zero value" (which for example is 0 for an int, or empty string for a string).  So there is no such thing as a non-existent or uninitialized field.

Tanmay Das

unread,
Apr 12, 2020, 5:12:16 PM4/12/20
to golang-nuts
Hi Jake,
Thanks for the wishes. BTW, this is not my first statically typed language, I know a little bit of C and Java. I was under the impression that Go is capable of some dynamic behavior. Maybe things like Go's type inference, duck typing, empty interface{} led me to believe that. All these type-related bindings can be resolved at compile-time. So I was thinking, if the compiler can do some extra work for resolving the types, maybe it could add a few more steps to keep track of which function to call when an undefined method is accessed.

robert engels

unread,
Apr 12, 2020, 5:49:59 PM4/12/20
to Tanmay Das, golang-nuts
You probably want to use interfaces. You can do a lot of “seemingly dynamic” programming with interfaces.

There are statically typed languages that pretty dynamic - Java with reflection and proxies - but Go is also statically compiled which makes the options limited - which is usually a good thing (e.g. over the dynamic unmaintainable mess that is Python).

> On Apr 12, 2020, at 12:12 PM, Tanmay Das <tanma...@gmail.com> wrote:
>
> Hi Jake,
> Thanks for the wishes. BTW, this is not my first statically typed language, I know a little bit of C and Java. I was under the impression that Go is capable of some dynamic behavior. Maybe things like Go's type inference, duck typing, empty interface{} led me to believe that. All these type-related bindings can be resolved at compile-time. So I was thinking, if the compiler can do some extra work for resolving the types, maybe it could add a few more steps to keep track of which function to call when an undefined method is accessed.
>
> --
> 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.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/271f39fa-bc9d-4a09-8773-09aee010d71a%40googlegroups.com.

Amnon Baron Cohen

unread,
Apr 12, 2020, 7:37:09 PM4/12/20
to golang-nuts
Go is a simple language. 

Code in Go does what it says. No magic. 

That is its beauty. That is its power.

Tanmay Das

unread,
Apr 13, 2020, 3:03:25 AM4/13/20
to golang-nuts
Very true.

Brian Candler

unread,
Apr 13, 2020, 8:56:49 AM4/13/20
to golang-nuts
On Sunday, 12 April 2020 18:12:16 UTC+1, Tanmay Das wrote:
this is not my first statically typed language, I know a little bit of C and Java. I was under the impression that Go is capable of some dynamic behavior. Maybe things like Go's type inference, duck typing, empty interface{} led me to believe that. All these type-related bindings can be resolved at compile-time. So I was thinking, if the compiler can do some extra work for resolving the types, maybe it could add a few more steps to keep track of which function to call when an undefined method is accessed.

There's no type inference in go, except for defining a variable and initializing it from an expression at the same time:

    v := foo()

In this case you don't need to declare the type of v, because it's implied from the return type of foo.

The nearest to dynamic typing (and indeed duck typing) is interfaces.  You can define an interface such as:

    type Foo interface {
        Bar()
    }

and then declare a variable of that type:

    var v Foo

When you later assign something to var v, you can only assign a value of some type which includes the Bar() method.  This is statically enforced (at compile time): you simply can't write a program which assigns a value which doesn't have the Bar() method.

Note that the types you create which include a Bar() method *don't* need to declare that they implement the Foo interface; this is implicit by the fact that they have the correct methods, which makes it rather like duck-typing.

Interfaces with only a single method are very common, since the same object can implement many different interfaces if required.

This feature gives a huge amount of flexibility.  For example, the io.Reader interface is simple but pervasive.

Tanmay Das

unread,
Apr 13, 2020, 10:13:25 AM4/13/20
to golang-nuts
Thanks for the clarification, Brian!
Reply all
Reply to author
Forward
0 new messages