Pattern for "include"ing class methods?

I'm doing some meta-programming where I want to add the same
instance and class methods to many other existing classes,
which I don't wish to re-superclass.

include <module> works nicely for including instance methods,
but to make class extensions as well, I need to use extend
with a module that uses class_def (from _why's metaid.rb)

Is there a way to avoid having to make two separate extension
modules and apply them separately, as in:

class Foo < ...whatever...
  include InstanceExtensions
  extend ClassExtensions
  ...
end

What I'd like is to define one extension module having both
class and instance methods, and insert them both into my class
with one statement. If I include and extend the same module,
like Facet's include_and_extend used to do, I get the instance
methods defined on the classes as well as the instances.

Any thoughts?

Clifford Heath.

module M
    module ClassMethods
    end

    module InstanceMethods
    end

    def M.inherited other
      other.send :extend, ClassMethods
      other.send :include InstanceMethods
   end
end

a @ http://codeforpeople.com/

···

On Feb 5, 2008, at 8:59 PM, Clifford Heath wrote:

I'm doing some meta-programming where I want to add the same
instance and class methods to many other existing classes,
which I don't wish to re-superclass.

include <module> works nicely for including instance methods,
but to make class extensions as well, I need to use extend
with a module that uses class_def (from _why's metaid.rb)

Is there a way to avoid having to make two separate extension
modules and apply them separately, as in:

class Foo < ...whatever...
include InstanceExtensions
extend ClassExtensions
...
end

What I'd like is to define one extension module having both
class and instance methods, and insert them both into my class
with one statement. If I include and extend the same module,
like Facet's include_and_extend used to do, I get the instance
methods defined on the classes as well as the instances.

Any thoughts?

Clifford Heath.

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

ara howard wrote:

module M
    module ClassMethods
    end

    module InstanceMethods
    end

    def M.inherited other
      other.send :extend, ClassMethods
      other.send :include InstanceMethods
   end
end

Interesting idea, but it doesn't seem to work, and I don't see
how it could (though I've mangled it into something different
that does work).

How and when should module M get used, and how does inherited
get called?

My look at the Ruby doc says the "inherited" callback only works
on classes, not on modules...? Is this a 1.9 thing? If I change
M to a class, then of course I can't use it as the argument to
include or extend :-).

What I *did* get to work was to add a method to class Module that
does the include and extend. Which I guess I knew I could do anyhow...

Clifford Heath.

What stops you from doing

module InstMeths
end

module ClassMeths
end

def adjust(cl)
  cl.extend ClassMeths
  cl.send :include, InstMeths
end

adjust MyClass
adjust YourClass

or even

set_of_classes.each {|cl| adjust cl}

? (probably with a more expressive method name than "adjust")

Kind regards

robert

···

2008/2/6, Clifford Heath <no@spam.please.net>:

ara howard wrote:
> module M
> module ClassMethods
> end
>
> module InstanceMethods
> end
>
> def M.inherited other
> other.send :extend, ClassMethods
> other.send :include InstanceMethods
> end
> end

Interesting idea, but it doesn't seem to work, and I don't see
how it could (though I've mangled it into something different
that does work).

How and when should module M get used, and how does inherited
get called?

My look at the Ruby doc says the "inherited" callback only works
on classes, not on modules...? Is this a 1.9 thing? If I change
M to a class, then of course I can't use it as the argument to
include or extend :-).

What I *did* get to work was to add a method to class Module that
does the include and extend. Which I guess I knew I could do anyhow...

--
use.inject do |as, often| as.you_can - without end

Alle Wednesday 06 February 2008, Clifford Heath ha scritto:

ara howard wrote:
> module M
> module ClassMethods
> end
>
> module InstanceMethods
> end
>
> def M.inherited other
> other.send :extend, ClassMethods
> other.send :include InstanceMethods
> end
> end

Interesting idea, but it doesn't seem to work, and I don't see
how it could (though I've mangled it into something different
that does work).

How and when should module M get used, and how does inherited
get called?

My look at the Ruby doc says the "inherited" callback only works
on classes, not on modules...? Is this a 1.9 thing? If I change
M to a class, then of course I can't use it as the argument to
include or extend :-).

What I *did* get to work was to add a method to class Module that
does the include and extend. Which I guess I knew I could do anyhow...

Clifford Heath.

I think you need M.included, not M.inherited:

module M

  module ClassMethods
    def m1
      puts "m1"
    end
  end

  module InstanceMethods
    def m2
      puts "m2"
    end
  end

  def self.included other
    other.send :include, InstanceMethods
    other.send :extend, ClassMethods
  end
end

class C
  include M
end

C.m1
C.new.m2

Stefano

Stefano

yeah - typo - sorry.

it definitely works - i use it everywhere...

cheers.

a @ http://codeforpeople.com/

···

On Feb 6, 2008, at 8:54 AM, Stefano Crocco wrote:

I think you need M.included, not M.inherited:

--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama

ara howard wrote:

···

On Feb 6, 2008, at 8:54 AM, Stefano Crocco wrote:

I think you need M.included, not M.inherited:

yeah - typo - sorry.
it definitely works - i use it everywhere...

Thanks all, exactly what I wanted, works like a charm.

Clifford Heath.