tags:

views:

38

answers:

2

Hi,

I am wondering, why is an included module's methods mixed in to any subsequent class definitions (as if the class included it in itself)?

module Foo
  def bar
    print "#{self}\n"
  end
end

class Bar
end

begin
  Bar.bar
rescue NoMethodError
  puts "There is no Bar.bar\n"
end

include Foo

bar
Bar.bar
Bar.new.bar

prints:

There is no Bar.bar
main
Bar
#<Bar:0xb73f2048>

Is this the expected behavior? Why?

+2  A: 

When you include Foo in your program but outside of any class or method then it is included in to the current scope which is the main object.

You could test this by modifying your bar method to the following

  def bar
    print "InBar class: #{self.class} value: #{self}\n"
  end

And then adding the following 2 lines at the end

2.bar
Fixnum.bar

This would give you the following output

There is no Bar.bar
InBar class: Object value: main
InBar class: Class value: Bar
InBar class: Bar value: #<Bar:0x21ecec>
InBar class: Fixnum value: 2
InBar class: Class value: Fixnum
Steve Weet
`main` actually isn't a class it's an object. As such `include` shouldn't (strictly) be available at top-level. Nonetheless `include` is made available as a special case (convenience method) but it's behaviour is to mix the module into `Object`
banister
@banister. Thanks fingers faster than brain. Edited appropriately
Steve Weet
+2  A: 

an include at top-level mixes the module into Object. In so far as it's mixed into Object it's available as an instance method on everything.

banister