P
Phrogz
Summary:
I'm writing a module that needs a specific property/method to be
supplied by the user. How do you handle this?
Details:
For my module to be effective, it needs the user to implement either an
instance property (or method that returns a value)that 'describes' the
instance. This should _not_ be unique for each instance, so #object_id
is out.
It would be effective to simply say "Hey, if you include this module in
your class, you need to supply @foo or else it'll break". But for some
reason that seems wrong to me.
The best way I've come up with is the following. Do you have a better
suggestion?
module Foo
def self.included( klass )
klass.class_eval{
def self.foo_name=( block )
@name_block = block
end
def self.foo_name
@name_block
end
}
end
def foo_name
self.class.foo_name.call( self )
end
def same_as?( other_foo )
self.foo_name == other_foo.foo_name
end
end
class Bar
include Foo
self.foo_name = lambda{ |bar| bar.name }
attr_reader :name
def initialize( name )
@name = name
end
end
b1a = Bar.new( "Fred" )
b1b = Bar.new( "Fred" )
b2 = Bar.new( "Jim" )
p b1a == b1b #=> false
p b1a.same_as?( b1b ) #=> true
p b1a.same_as?( b2 ) #=> false
I'm writing a module that needs a specific property/method to be
supplied by the user. How do you handle this?
Details:
For my module to be effective, it needs the user to implement either an
instance property (or method that returns a value)that 'describes' the
instance. This should _not_ be unique for each instance, so #object_id
is out.
It would be effective to simply say "Hey, if you include this module in
your class, you need to supply @foo or else it'll break". But for some
reason that seems wrong to me.
The best way I've come up with is the following. Do you have a better
suggestion?
module Foo
def self.included( klass )
klass.class_eval{
def self.foo_name=( block )
@name_block = block
end
def self.foo_name
@name_block
end
}
end
def foo_name
self.class.foo_name.call( self )
end
def same_as?( other_foo )
self.foo_name == other_foo.foo_name
end
end
class Bar
include Foo
self.foo_name = lambda{ |bar| bar.name }
attr_reader :name
def initialize( name )
@name = name
end
end
b1a = Bar.new( "Fred" )
b1b = Bar.new( "Fred" )
b2 = Bar.new( "Jim" )
p b1a == b1b #=> false
p b1a.same_as?( b1b ) #=> true
p b1a.same_as?( b2 ) #=> false