Forum: Ruby "exporting" module 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.
Xavier N. (Guest)
on 2006-02-21 16:32
(Received via mailing list)
Is there standard idiom to add module methods to classes that mixin
them? (Heh, is "mixin" also a verb in Ruby?)

That is, I would like class C to croak:

   module M
     def self.croak
       puts "croak!"
     end
   end

   class C
     include M
     croak
   end

-- fxn
Mark V. (Guest)
on 2006-02-21 16:44
(Received via mailing list)
On 2/21/06, Xavier N. <removed_email_address@domain.invalid> wrote:
>
>    class C
>      include M
>      croak
>    end

When you say you want class C to croak, I assume you really mean you'd
like for objects from the class C to be able to croak. Remove the line
"croak" from the class C definition and do this.

c = C.new
c.croak

The rest of your code looks fine.
unknown (Guest)
on 2006-02-21 16:59
(Received via mailing list)
Hi --

On Tue, 21 Feb 2006, Mark V. wrote:

>>    end
> c = C.new
> c.croak
>
> The rest of your code looks fine.

I don't think that's what Xavier wanted; I think he wanted C to be
able to call M.croak.  (Also, in your example, c doesn't respond to
croak.)

This is an often-discussed question.  Some common answers:

   1. module M; def croak; ....; end;  class C; extend M; end
   2. put "class methods" into M::ClassMethods, and then write
      an M#included hook that extends C with M::ClassMethods
      while also including the rest of M in C.
   3. don't do that, because if you want two modules, just write
      two modules in the first place and don't shoehorn "class
      methods" in as instance methods of an inner module
   4. ask Matz to make some fundamental change so that include M
      does what people call "what you expect" (which is not what
      I expect)

And probably more :-)  I would give gold, silver, and bronze to #1,
#3, and #2, in that order.


David

--
David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
James G. (Guest)
on 2006-02-21 17:14
(Received via mailing list)
On Feb 21, 2006, at 8:31 AM, Xavier N. wrote:

>
>   class C
>     include M
>     croak
>   end

I tend to do it like this:

Module M
   extend self  # duplicate instance methods as class methods

   def croak
     puts "Croak!"
   end
end

class C
   extend M  # class-level mixin
   croak
end

Hope that helps.

James Edward G. II
Mark V. (Guest)
on 2006-02-21 17:20
(Received via mailing list)
On 2/21/06, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:

> I don't think that's what Xavier wanted; I think he wanted C to be
> able to call M.croak.  (Also, in your example, c doesn't respond to
> croak.)

Wow!  I have a fundamental misunderstanding of mixins apparently. I
see that you are correct. c doesn't respond to croak in the following
code. However, I don't understand why. Doesn't the include add
instance methods from the module M to the class C?

module M
  def self.croak
    puts 'croak'
  end
end

class C
  include M
end

c = C.new
c.croak
unknown (Guest)
on 2006-02-21 17:42
(Received via mailing list)
Hi --

On Wed, 22 Feb 2006, Mark V. wrote:

>
> c = C.new
> c.croak

Yes, but croak isn't an instance method :-)  (Note the "self." part.)


David

--
David A. Black (removed_email_address@domain.invalid)
Ruby Power and Light (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! http://www.manning.com/books/black
Mark V. (Guest)
on 2006-02-21 17:51
(Received via mailing list)
On 2/21/06, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> > Wow!  I have a fundamental misunderstanding of mixins apparently. I
> > class C
> >  include M
> > end
> >
> > c = C.new
> > c.croak
>
> Yes, but croak isn't an instance method :-)  (Note the "self." part.)

Silly me!  I briefly crossed things in my mind and thought that
including "self." made it an instance method ... and I thought I got
enough sleep last night. ;-)
This topic is locked and can not be replied to.