Mixin a module method as a class method

Discussion in 'Ruby' started by Farrel Lifson, Oct 18, 2006.

  1. Is it possible to mix in a module method to become a class method? I'd
    like to define the method_added method in a module and then mix it
    into a class like so
    module Foo
    def self.method_added(method)
    puts "Added #{method}"
    end
    end

    class Bar
    include Foo
    def bar
    end
    def baz
    end
    end
    So that I get
    Added bar
    Added baz
    printed out. Is there any way to do this besides making Foo a class
    and subclassing Foo from it?

    Farrel
     
    Farrel Lifson, Oct 18, 2006
    #1
    1. Advertising

  2. Farrel Lifson

    Jan Svitok Guest

    On 10/18/06, Farrel Lifson <> wrote:
    > Is it possible to mix in a module method to become a class method? I'd
    > like to define the method_added method in a module and then mix it
    > into a class like so
    > module Foo
    > def self.method_added(method)
    > puts "Added #{method}"
    > end
    > end
    >
    > class Bar
    > include Foo
    > def bar
    > end
    > def baz
    > end
    > end
    > So that I get
    > Added bar
    > Added baz
    > printed out. Is there any way to do this besides making Foo a class
    > and subclassing Foo from it?
    >
    > Farrel


    See previous thread: 'Ruby for Rails p.462-464 - why include vs.
    extend?' or api.rubyon rails and there *::*::ClassMethods

    basicly something like this:

    module A
    module M
    module ClassMethods
    def some_method
    #...
    end

    def included(c)
    c.extend(ClassMethods)
    end
    end
    end

    and then a class later that does this:

    class B
    include A::M
    end
     
    Jan Svitok, Oct 18, 2006
    #2
    1. Advertising

  3. Farrel Lifson

    Phrogz Guest

    Farrel Lifson wrote:
    > Is it possible to mix in a module method to become a class method? I'd
    > like to define the method_added method in a module and then mix it
    > into a class like so

    [...snip...]
    > So that I get
    > Added bar
    > Added baz
    > printed out.


    module Foo
    def method_added(method)
    puts "Added #{method}"
    end
    end
    class Bar
    extend Foo
    def bar; end
    def baz; end
    end
     
    Phrogz, Oct 18, 2006
    #3
  4. Farrel Lifson

    Phrogz Guest

    Jan Svitok wrote:
    > module A
    > module M
    > module ClassMethods
    > def some_method
    > #...
    > end
    >
    > def included(c)
    > c.extend(ClassMethods)
    > end
    > end
    > end


    The extra ClassMethods module is needed because self methods of a
    module are never mixed into the lookup flow. See note #3 at
    http://phrogz.net/RubyLibs/RubyMethodLookupFlow.png - using 'extend'
    instead of 'include' causes the left end of the mixed-in module line to
    come from the 'class methods' side of the extended class, but doesn't
    change that the right end always points to the 'instance' methods of
    the module.

    (Right?)
     
    Phrogz, Oct 18, 2006
    #4
  5. Farrel Lifson

    Trans Guest

    Farrel Lifson wrote:
    > Is it possible to mix in a module method to become a class method? I'd
    > like to define the method_added method in a module and then mix it
    > into a class like so
    > module Foo
    > def self.method_added(method)
    > puts "Added #{method}"
    > end
    > end
    >
    > class Bar
    > include Foo
    > def bar
    > end
    > def baz
    > end
    > end
    > So that I get
    > Added bar
    > Added baz
    > printed out. Is there any way to do this besides making Foo a class
    > and subclassing Foo from it?


    Search ruby-talk for #class_extension.

    require 'facet/module/calss_extension'

    module Foo
    class_extension {
    def method_added(method)
    puts "Added #{method}"
    end
    }
    end

    T.
     
    Trans, Oct 18, 2006
    #5
  6. Farrel Lifson

    Guest

    On Wed, 18 Oct 2006, Farrel Lifson wrote:

    > Is it possible to mix in a module method to become a class method? I'd
    > like to define the method_added method in a module and then mix it
    > into a class like so
    > module Foo
    > def self.method_added(method)
    > puts "Added #{method}"
    > end
    > end
    >
    > class Bar
    > include Foo
    > def bar
    > end
    > def baz
    > end
    > end
    > So that I get
    > Added bar
    > Added baz
    > printed out. Is there any way to do this besides making Foo a class
    > and subclassing Foo from it?
    >
    > Farrel


    harp:~ > cat a.rb
    module Foo
    #def self.method_added(method)
    def method_added(method)
    puts "Added #{method}"
    end
    end

    class Bar
    #include Foo
    extend Foo
    def bar
    end
    def baz
    end
    end

    harp:~ > ruby a.rb
    Added bar
    Added baz


    if you need both instance and class methods to be in Foo, then you'll want:


    harp:~ > cat a.rb
    module Foo
    #def self.method_added(method)
    module ClassMethods
    def method_added(method)
    puts "Added #{method}"
    end
    end
    module InstanceMethods
    def foo() 42 end
    end
    def self.included other
    other.module_eval{
    extend ClassMethods
    include InstanceMethods
    }
    end
    end

    class Bar
    include Foo
    def bar
    end
    def baz
    end
    end

    p Bar.new.foo


    harp:~ > ruby a.rb
    Added bar
    Added baz
    42


    -a
    --
    my religion is very simple. my religion is kindness. -- the dalai lama
     
    , Oct 18, 2006
    #6
  7. Farrel Lifson

    Verno Miller Guest

    Verno Miller, Oct 18, 2006
    #7
  8. On 10/18/06, <> wrote:
    > On Wed, 18 Oct 2006, Farrel Lifson wrote:
    >
    > > Is it possible to mix in a module method to become a class method? I'd
    > > like to define the method_added method in a module and then mix it
    > > into a class like so
    > > module Foo
    > > def self.method_added(method)
    > > puts "Added #{method}"
    > > end
    > > end
    > >
    > > class Bar
    > > include Foo
    > > def bar
    > > end
    > > def baz
    > > end
    > > end
    > > So that I get
    > > Added bar
    > > Added baz
    > > printed out. Is there any way to do this besides making Foo a class
    > > and subclassing Foo from it?
    > >
    > > Farrel

    >
    > harp:~ > cat a.rb
    > module Foo
    > #def self.method_added(method)
    > def method_added(method)
    > puts "Added #{method}"
    > end
    > end
    >
    > class Bar
    > #include Foo
    > extend Foo
    > def bar
    > end
    > def baz
    > end
    > end
    >
    > harp:~ > ruby a.rb
    > Added bar
    > Added baz
    >
    >
    > if you need both instance and class methods to be in Foo, then you'll want:
    >
    >
    > harp:~ > cat a.rb
    > module Foo
    > #def self.method_added(method)
    > module ClassMethods
    > def method_added(method)
    > puts "Added #{method}"
    > end
    > end
    > module InstanceMethods
    > def foo() 42 end
    > end
    > def self.included other
    > other.module_eval{
    > extend ClassMethods
    > include InstanceMethods
    > }
    > end
    > end
    >
    > class Bar
    > include Foo
    > def bar
    > end
    > def baz
    > end
    > end
    >
    > p Bar.new.foo
    >
    >
    > harp:~ > ruby a.rb
    > Added bar
    > Added baz
    > 42
    >
    >
    > -a
    > --
    > my religion is very simple. my religion is kindness. -- the dalai lama


    No need for the separate module for instance methods;

    rick@frodo:/public/rubyscripts$ cat a1.rb
    module Foo

    module ClassMethods
    def method_added(method)
    puts "Added #{method}"
    end
    end

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

    def foo
    42
    end
    end

    class Bar
    include Foo

    def bar
    end

    def baz
    end
    end

    p Bar.new.foo
    rick@frodo:/public/rubyscripts$ ruby a1.rb
    Added bar
    Added baz
    42


    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, Oct 19, 2006
    #8
  9. Farrel Lifson

    Guest

    On Thu, 19 Oct 2006, Rick DeNatale wrote:

    >
    > No need for the separate module for instance methods;


    no. you are correct, it's just a convention which signifies to the
    uninitiated what is happening.

    regards.


    -a
    --
    my religion is very simple. my religion is kindness. -- the dalai lama
     
    , Oct 19, 2006
    #9
  10. Farrel Lifson

    Trans Guest

    Verno Miller wrote:
    > > Posted by Farrel Lifson (Guest)
    > > on 18.10.2006 15:05
    > >
    > > Is it possible to mix in a module method to become a class method?

    >
    >
    > Yet another approach:
    >
    > http://redcorundum.blogspot.com/2006/06/mixing-in-class-methods.html


    This looks like much like #class_extension. How does this differ?

    An interesting side note to this. I recetnly ran into the opposite case
    wehere I wanted to prevent a class method (of a class) from being
    inherited by the subclass. I had to use some method programming tricks
    to undef the particular method. This further leads me to believe that
    the best solution is to allow deignation of methods as inheritable or
    not in much the same way we designate private/public. Classes' class
    methods would be inheritable be default, module's not. This could also
    be used for instance methods to create namespace local methods.

    T.
     
    Trans, Oct 19, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mac
    Replies:
    1
    Views:
    643
  2. Ben
    Replies:
    3
    Views:
    258
  3. Sijo Kg

    class, Module and Mixin

    Sijo Kg, Sep 24, 2009, in forum: Ruby
    Replies:
    1
    Views:
    136
    Robert Klemme
    Sep 24, 2009
  4. John Lane
    Replies:
    6
    Views:
    209
    John Lane
    Feb 9, 2010
  5. JP Billaud

    Module Mixin & Class Variables

    JP Billaud, Mar 6, 2011, in forum: Ruby
    Replies:
    0
    Views:
    148
    JP Billaud
    Mar 6, 2011
Loading...

Share This Page