This caused me a small headache the other day. By including a module, an
instance method suddenly becomes accessible as a module method. Seems
unintuitive, I’m curious to understand the reasoning behind it.
module Foo
module Bar
def hello
‘hello’
end
end
end
Foo::Bar.hello # => -:9: undefined method `hello’ for Foo::Bar:Module
(NoMethodError)
At the top level, the include will include the module in Object:
Where is the module before it is included?
I’m not sure what you mean. Can you elaborate?
David
I would think the name Foo would be visible just like the name of a
method is visible, e.g.:
def greet
puts “hello”
end
According to pickaxe2 p. 346, greet is inserted as a private method of
Object, and hence can be called in any context without a receiver, i.e.
without 'some_obj." in front of the method name.
In the op’s example, there is a module named Foo. Is Foo just a free
floating object? Or, is it an attribute of some omnipresent object?
Where is the module before it is included?
puts “hello”
end
According to pickaxe2 p. 346, greet is inserted as a private method of
Object, and hence can be called in any context without a receiver, i.e.
without 'some_obj." in front of the method name.
In the op’s example, there is a module named Foo. Is Foo just a free
floating object? Or, is it an attribute of some omnipresent object?
Constants you define at the top level are owned by Object:
class C
end
module M
end
X = 1
p Object.constants.grep(/^(C|M|X)$/) # => [“X”, “C”, “M”]
Constants you define at the top level are owned by Object:
Is an include always necessary to be able to call a module’s instance
methods?
Yes I believe so, that is include or extend
irb(main):001:0> module M
irb(main):002:1> def a; 42 end
irb(main):003:1> end
=> nil
irb(main):009:0> m = M.instance_method(“a”)
=> #<UnboundMethod: M#a>
irb(main):010:0> m.bind(“a”).call
TypeError: bind argument must be an instance of M
from (irb):10:in `bind’
from (irb):10
from :0
irb(main):012:0> C = Class::new{ include M }
###################^^^^^^^
=> C
irb(main):013:0> m.bind(C.new).call
=> 42
irb(main):014:0> a=“42”
=> “42”
irb(main):015:0> a.extend M
###########^^^^^^
=> “42”
irb(main):016:0> m.bind(a).call
=> 42