How to overide "include" method?

A

Alexandre Mutel

I tried several way, but didn't found any to override the behavior of
the "include" method.
I would like to override it's behavior to accept a string as an argument
and perform a special include based on that.. so I tried something like
this:

class Module
def include(module1, *smth) # :doc:
puts "In my include #{self}"
if ( module1.is_a? String)
instance_eval(File.read(module1), module1)
else
super module1,*smth
end
end
end

without any success, this method is nether called.

Any ideas?
 
P

Phrogz

I tried several way, but didn't found any to override the behavior of
the "include" method.

# Class methods of classes inherit from instance methods of
# the Class class before they inherit from instance methods of Module.
# http://phrogz.net/RubyLibs/RubyMethodLookupFlow.png
class Class
def include(*args)
p "hi!"
super
end
end

module Bar; end

class Foo
include Bar #=> "hi!"
end

p Foo.ancestors
#=> [Foo, Bar, Object, Kernel]
 
A

Alexandre Mutel

Gavin said:
# Class methods of classes inherit from instance methods of
# the Class class before they inherit from instance methods of Module.
# http://phrogz.net/RubyLibs/RubyMethodLookupFlow.png

Thanks! Your example is working well until i use it inside a class
definition.

But when i'm trying to use it from the irb prompt, but the overloaded
include it's not called...
Is there a way to found from where the method is define? ( with
method:)include).something?), so i know where to define the overload...

For example, if i put the class overloading in a separate file
class_includer.rb
class Class
def include(*args)
p "hi!"
super
end
end

And from the irb :
require "class_includer"
include "test"

The method above is not called. It means that it's implemented elsewhere
in this case (outside a class definition, in the top level).

I tried to overload directly the include method in the irb, but it's not
working as well, very strange... well, i have probably to understand
more how scope on self is working!

So from the top level, where i can overload this "include" method?
 
P

Phrogz

Gavin Kistner wrote:
But when i'm trying to use it from the irb prompt, but the overloaded
include it's not called...
Is there a way to found from where the method is define? ( with
method:)include).something?), so i know where to define the overload...

Apparently not, since method:)include).source_location returns nil.

But you can see that the include at the top level is custom for main,
not the same include from modules:

irb(main):001:0> class Foo; end
=> nil

irb(main):002:0> [ method:)include), method:)include).owner ]
=> [#<Method: main.include>, #<Class:#<Object:0x000001008b8e58>>]

irb(main):003:0> [ Foo.method:)include), Foo.method:)include).owner ]
So from the top level, where i can overload this "include" method?

Good question. I'm not sure where main fits into the method lookup
flow. (But if someone tells me, I'll add it to the diagram :)
 
A

Alexandre Mutel

Gavin said:
Good question. I'm not sure where main fits into the method lookup
flow. (But if someone tells me, I'll add it to the diagram :)

Seems that overriding like this is working :

$x = method:)include)
def self.include(mod)
puts "Hi"
$x.call mod
end
 
A

Alexandre Mutel

In a cleaner way, it seems to work on the irb level:

class << self
alias :_old_include_method :include
def include(mod)
puts "Hi"
_old_include_method mod
end
end
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top