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 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 H…

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

methods defined on the classes as well as the instances.

Any thoughts?

Clifford H…

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/

ara howard wrote:

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 H…

2008/2/6, Clifford H. [email protected]:

  other.send :include InstanceMethods

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…

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

Alle Wednesday 06 February 2008, Clifford H. ha scritto:

  other.send :include InstanceMethods

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 H…

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

ara howard wrote:

On Feb 6, 2008, at 8:54 AM, Stefano C. 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 H…

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

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

yeah - typo - sorry.

it definitely works - i use it everywhere…

cheers.

a @ http://codeforpeople.com/