On Tue, Apr 11, 2006 at 02:46:24AM +0900, zdennis wrote:
Is there an easy way to extend classes with both class and object
methods at the same time?
irb(main):010:1* def self.included( clazz )
irb(main):011:2> clazz.extend( ClassLevelAddons )
irb(main):012:2> end
irb(main):013:1> end
The above lets M take care of the work, so your class doesn’t have to
think about it. This is the method that Robert K. was refering to,
Module::included
I was hoping that I was missing some clever way to do it with just one
module. Guess not. But the self.included hook is a good idea. The two
modules become an implementation detail, and thats good enough.
This is because you created the ‘create’ method as a class-like method
on the mdoule, a module method. You need to create it as an
instance level method. It seems to do this cleanly you’d want to
separate this into two modules, one for instance level methods
and one intended for class-level use:
irb(main):017:0> module ClassLevelAddons
irb(main):018:1> def create
irb(main):019:2> new
irb(main):020:2> end
irb(main):021:1> end
=> nil
irb(main):022:0> module InstanceLevelAddons
irb(main):023:1> def foo
irb(main):024:2> “bar”
irb(main):025:2> end
irb(main):026:1> end
=> nil
irb(main):027:0> class A
irb(main):028:1> extend ClassLevelAddons
irb(main):029:1> include InstanceLevelAddons
irb(main):030:1> end
=> A
irb(main):031:0> A.create
=> #<A:0xb7c9dc1c>
irb(main):032:0> A.new.foo
=> “bar”
For organizational concerns you could always let one module be in
charge:
irb(main):001:0> module M
irb(main):002:1> module ClassLevelAddons
irb(main):003:2> def create; new ; end
irb(main):004:2> end
irb(main):005:1>
irb(main):006:1* def foo
irb(main):007:2> “bar”
irb(main):008:2> end
irb(main):009:1>
irb(main):010:1* def self.included( clazz )
irb(main):011:2> clazz.extend( ClassLevelAddons )
irb(main):012:2> end
irb(main):013:1> end
=> nil
irb(main):014:0> class A ; include M; end
=> A
irb(main):015:0> A.create
=> #<A:0x2bfc5e8>
irb(main):016:0> A.new.foo
=> “bar”
irb(main):017:0>
The above lets M take care of the work, so your class doesn’t have to
think about it. This is the method that Robert K. was
refering to, Module::included
Zach
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org
think about it. This is the method that Robert K. was refering to,
Module::included
I was hoping that I was missing some clever way to do it with just one
module. Guess not. But the self.included hook is a good idea. The two
modules become an implementation detail, and thats good enough.
you can do it with one:
harp:~ > cat a.rb
module M
def a
self
end
def self.included other
other.extend self
super
end
end
I was thinking that Sam wasn’t looking for the same interface at both
the instance and class levels. I was thinking he wanted the
equivalent of if including Modules also brought in the module levels
methods.
module M
def self.foo
“foo”
end
def bar
“bar”
end
end
class A
include M
end
A.foo # => “foo”
A.new.bar => “bar”
Given the above code is what I think Sam was hoping to achieve, that’s
why I focused on giving the example of getting that
functionality using include/extend.
Zach
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org