tags:

views:

259

answers:

2

Imagine the following Ruby Module:

module Foo
  def inst_method
    puts "Called Foo.inst_method"
  end
  def self.class_method
    puts "Called Foo.class_method"
  end
end

Obviously Foo.class_method can be called without any class instances. However, what's happening to Foo.inst_method? Is it possible to call Foo.inst_method without previously including/extending a class?

Disclaimer: The question isn't focused on solving a real problem. I'm just trying to improve my understanding of the Ruby object system.

+1  A: 

My answer would be : "no you can't call module instance methods without first extending or including that module in a class"

now knowing ruby and all the meta programming trickery it contains there probably is a way to call it but it would be outside the intended use of modules

module Tester
  def inst_meth
    puts "test inst meth\n"
  end

  def self.meth
    puts "test self meth\n"
  end
end

begin
  Tester.meth
rescue;
  puts $!
end
begin
  Tester.inst_meth
rescue
  puts $!
end
begin
  Tester.new.inst_meth
rescue
  puts $!
end
begin
  extend Tester
  inst_meth
rescue
  puts $!
end
begin
  include Tester
  inst_meth
rescue
  puts $!
end

gives

>ruby test.rb
test self meth
undefined method `inst_meth' for Tester:Module
undefined method `new' for Tester:Module
 test inst meth
 test inst meth
Jean
+3  A: 

The primary purpose of instance methods within modules is to give that functionality to classes that include it.

"Mixing in" a module this way is most commonly used as a method of simulating multiple inheritance, or in other situations where inheritance is not the right paradigm (not quite a perfect "is a" relationship) but you want to share behavior. It's one more tool to keep your code DRY.

A good example of this in core Ruby is noting how Array and Hash can both be traveled and sorted, etc. They each get this functionality from the Enumerable module (each_with_index, select, reject, sort and more are all defined in the included module, not in the classes).

Ian Terrell