Discussion:
[jruby-user] overloading Java methods via a module
Mike Luu
2014-07-17 22:54:57 UTC
Permalink
I can’t seem to overload a Java class instance method via a module.

```
require 'java'
module A
def getComment
'via module'
end
end

Java::JavaNet::HttpCookie.send(:include, A)
Java::JavaNet::HttpCookie.new('k', 'v').getComment
```

the last line returns the original java definition when I want it to return my overloaded version

What does work is opening up the class…

```
require 'java'
class Java::JavaNet::HttpCookie
def getComment
'via class opening'
end
end
java.net.HttpCookie.new('k', 'v').getComment
```

note: I’m using HttpCookie as an example :)

Thanks,
Mike
---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email
Eric West
2014-07-18 02:28:42 UTC
Permalink
including a module won’t override the methods in the class it is included
into. For example, I’ll run some code on MRI to explain this:

$ ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]

module Cool
def lame
"Dude, that is so lame."
endend
class Hipster
include Cool

def lame
"You've probably never heard of it. Because you're lame."
endend

hipster = Hipster.new
hipster.lame # => "You've probably never heard of it. Because you're lame."

As you can see, despite including the module, it doesn’t override the
method #lame. Now what I can do is call #super, watch:

module Cool
def lame
"Dude, that is so lame."
endend
class Hipster
include Cool

def lame
"You've probably never heard of it. Because you're lame."
super
endend

hipster = Hipster.new
hipster.lame # => "Dude, that is so lame."

Including a module places that module into the class’s object heirarchy. So
it’s method’s don’t override the class’s instance methods. Instead, they
become super to those methods. One way to achieve something like the result
you are after is to extend the instance of the class with the module. Like
so:

module Cool
def lame
"Dude, that is so lame."
endend
class Hipster
def lame
"You've probably never heard of it. Because you're lame."
endend

hipster = Hipster.new.extend(Cool)
hipster.lame # => Dude, that is so lame.

Hope that explains what you are running into. This actually has nothing to
do with jruby and java, it is just how ruby works.
​
I can’t seem to overload a Java class instance method via a module.
```
require 'java'
module A
def getComment
'via module'
end
end
Java::JavaNet::HttpCookie.send(:include, A)
Java::JavaNet::HttpCookie.new('k', 'v').getComment
```
the last line returns the original java definition when I want it to
return my overloaded version
What does work is opening up the class

```
require 'java'
class Java::JavaNet::HttpCookie
def getComment
'via class opening'
end
end
java.net.HttpCookie.new('k', 'v').getComment
```
note: I’m using HttpCookie as an example :)
Thanks,
Mike
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Eric West
2014-07-18 17:46:00 UTC
Permalink
By the way, include has a special hook, included that gets called whenever
include is used. A lot of Rails code uses this hook to change include‘s
behavior. For instance, making include behave more like extend. This may be
why Ruby’s default behavior was surprising.
​
Post by Eric West
including a module won’t override the methods in the class it is included
$ ruby -v
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]
module Cool
def lame
"Dude, that is so lame."
endend
class Hipster
include Cool
def lame
"You've probably never heard of it. Because you're lame."
endend
hipster = Hipster.new
hipster.lame # => "You've probably never heard of it. Because you're lame."
As you can see, despite including the module, it doesn’t override the
module Cool
def lame
"Dude, that is so lame."
endend
class Hipster
include Cool
def lame
"You've probably never heard of it. Because you're lame."
super
endend
hipster = Hipster.new
hipster.lame # => "Dude, that is so lame."
Including a module places that module into the class’s object heirarchy.
So it’s method’s don’t override the class’s instance methods. Instead, they
become super to those methods. One way to achieve something like the result
you are after is to extend the instance of the class with the module. Like
module Cool
def lame
"Dude, that is so lame."
endend
class Hipster
def lame
"You've probably never heard of it. Because you're lame."
endend
hipster = Hipster.new.extend(Cool)
hipster.lame # => Dude, that is so lame.
Hope that explains what you are running into. This actually has nothing to
do with jruby and java, it is just how ruby works.
​
I can’t seem to overload a Java class instance method via a module.
```
require 'java'
module A
def getComment
'via module'
end
end
Java::JavaNet::HttpCookie.send(:include, A)
Java::JavaNet::HttpCookie.new('k', 'v').getComment
```
the last line returns the original java definition when I want it to
return my overloaded version
What does work is opening up the class

```
require 'java'
class Java::JavaNet::HttpCookie
def getComment
'via class opening'
end
end
java.net.HttpCookie.new('k', 'v').getComment
```
note: I’m using HttpCookie as an example :)
Thanks,
Mike
---------------------------------------------------------------------
http://xircles.codehaus.org/manage_email
Loading...