Curious include behavior

T

Tom Werner

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

* Libraries:
Chronic (chronic.rubyforge.org)
God (god.rubyforge.org)
Fuzed (fuzed.rubyforge.org)
* Site:
rubyisawesome.com
 
D

David A. Black

Hi --

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"

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

--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
 
D

David A. Black

Hi --

Where is the module before it is included?

I'm not sure what you mean. Can you elaborate?


David

--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
 
7

7stud --

David said:
Hi --



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?
 
D

David A. Black

Hi --

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?

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

--
Upcoming training from Ruby Power and Light, LLC:
* Intro to Ruby on Rails, Edison, NJ, October 23-26
* Advancing with Rails, Edison, NJ, November 6-9
Both taught by David A. Black.
See http://www.rubypal.com for more info!
 
R

Robert Dober

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
 

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,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top