Curious include behavior

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)

include Foo::Bar

Foo::Bar.hello # => “hello”


Tom Preston-Werner

David A. Black wrote:

At the top level, the include will include the module in Object:

Where is the module before it is included?

Hi –

On Sat, 29 Sep 2007, Tom W. wrote:

end

Foo::Bar.hello # => -:9: undefined method `hello’ for Foo::Bar:Module
(NoMethodError)

include Foo::Bar

Foo::Bar.hello # => “hello”

At the top level, the include will include the module in Object:

ruby -e ‘include Module.new; p Object.ancestors’
[Object, #Module:0x2592c, Kernel]

whereupon all objects will respond to its methods.

David

Hi –

On Sat, 29 Sep 2007, 7stud – wrote:

David A. Black wrote:

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

David A. Black wrote:

Hi –

On Sat, 29 Sep 2007, 7stud – wrote:

David A. Black wrote:

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?

Hi –

On Sat, 29 Sep 2007, 7stud – wrote:

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”]

David

On 9/30/07, 7stud – [email protected] wrote:

David A. Black wrote:

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

HTH
Robert

David A. Black wrote:

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?