Forum: Ruby modules and class methods.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Cf8586cf56fec72eb20a52e6797fea31?d=identicon&s=25 Brad Phelan (Guest)
on 2007-05-04 16:00
(Received via mailing list)
Why does this not work!

########################################
module Foo
     def self.foo a
  puts a
     end
end

class Bar
    include Foo
    foo "hello"
end

foo.rb:20: undefined method `foo' for Bar:Class (NoMethodError)
####################################

but this does

class Bar
    def self.foo a
  puts a
     end
    foo "hello"
end



What am I misunderstanding about modules????
E34b5cae57e0dd170114dba444e37852?d=identicon&s=25 Logan Capaldo (Guest)
on 2007-05-04 16:17
(Received via mailing list)
On 5/4/07, Brad Phelan <phelan@tttech.ttt> wrote:
> class Bar
>     def self.foo a
> Brad
> http://xtargets.com
>
> Module inclusion does not include singleton methods.

There are a few alternatives, the clearest one IMO being:

module Foo
   def foo a # note no self.
      puts a
   end
end

class Bar
   extend Foo # note extend, _not_include
   foo "hello"
end


The other option is to augment the include procedure. Ruby provides a
hook
Module#included.

module Foo
    def self.included(including_class_or_module)
       class << including_class_or_module
          def foo a
             puts a
          end
       end
   end
end

class Bar
   include Foo
   foo "hello"
end


Usually when people do this and a module contains both singleton methods
and
instance methods it will look something like:

module Foo
   def inst_meth1
   end

   def inst_meth1
   end

   module ClassMethods
       def foo a
          puts a
       end
  end

  def self.included(other)
     other.extend ClassMethods
  end
end

class Bar
  include Foo
  foo "hello"
end

Finally, you can of course use classes and plain old inheritance:

class Foo
   def self.foo a
      puts a
   end
end

class Bar < Foo
   foo "hello"
end
Cf8586cf56fec72eb20a52e6797fea31?d=identicon&s=25 Brad Phelan (Guest)
on 2007-09-25 23:00
(Received via mailing list)
>       puts "here"
>
> David
>

Now that is the sneaky little hook I was looking for.

Thanks

Brad
Cf8586cf56fec72eb20a52e6797fea31?d=identicon&s=25 Brad Phelan (Guest)
on 2007-09-25 23:03
(Received via mailing list)
Brad Phelan wrote:
>    include Foo
>     puts a
> http://xtargets.com
The below code obviously work the way I wish

module Foo
    def foo
       puts "a"
    end
end

class Bar
    extend Foo
    puts foo
end

however is there any way to get the same effect by using include. I
would like to mix in class and instance methods in one call. It seems
I can do one or the other but not both at the same time. Is that
correct?
1fba4539b6cafe2e60a2916fa184fc2f?d=identicon&s=25 unknown (Guest)
on 2007-09-25 23:04
(Received via mailing list)
Hi --

On Fri, 4 May 2007, Brad Phelan wrote:

>> class Bar
>>    def self.foo a
>> Brad
> class Bar
>   extend Foo
>   puts foo
> end
>
> however is there any way to get the same effect by using include. I would
> like to mix in class and instance methods in one call. It seems
> I can do one or the other but not both at the same time. Is that
> correct?

Basically, yes: mixing in a module inserts the module in only one
method lookup path, and a class and its instances generally have very
different lookup paths.

You can use the inherited hook in Module to do both -- for example:

   module M
     def self.included(c)
       m = self
       c.class_eval { extend m }
     end

     def meth
       puts "here"
     end
   end

   class C
     include M
   end

   C.meth          # here
   C.new.meth      # here


David
This topic is locked and can not be replied to.