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

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

Hi --

···

On Sat, 29 Sep 2007, Tom Werner wrote:

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

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!

David A. Black wrote:

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

Where is the module before it is included?

···

--
Posted via http://www.ruby-forum.com/\.

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

--
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!

David A. Black wrote:

Hi --

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?

···

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

--
Posted via http://www.ruby-forum.com/\.

Hi --

David A. Black wrote:

Hi --

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?

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 Sat, 29 Sep 2007, 7stud -- wrote:

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

--
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!

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?

···

--
Posted via http://www.ruby-forum.com/\.

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

···

On 9/30/07, 7stud -- <dolgun@excite.com> wrote:
        from :0

--
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/