[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Customizable Mixin

Gavin Kistner

7/15/2005 11:48:00 PM

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

4 Answers

Daniel Brockman

7/16/2005 12:02:00 AM

0

Devin Mullins

7/16/2005 12:10:00 AM

0

Phrogz wrote:

>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.
>
>
Why? Enumerable requires you to supply #each.

Another possibility:

module Foo
def foo_name=(foo_name)
@foo_name = foo_name
end
end

class Bar
include Foo
def initialize(name)
self.foo_name = name
end
end

Your way seems like a lot of (confusing, to me) overhead which not much
benefit, pragmatic or idealogical. But I could be missing something.

Devin



Devin Mullins

7/16/2005 12:15:00 AM

0

Or, for that Railsy flair:

module Foo
end

class Object
def extend_foo(name)
extend Foo
@foo_name = name
end
end

class Bar
def initialize(name)
extend_foo name
end
end

Devin

Devin Mullins wrote:

> Phrogz wrote:
>
>> 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.
>>
>>
> Why? Enumerable requires you to supply #each.
>
> Another possibility:
>
> module Foo
> def foo_name=(foo_name)
> @foo_name = foo_name
> end
> end
>
> class Bar
> include Foo
> def initialize(name)
> self.foo_name = name
> end
> end
>
> Your way seems like a lot of (confusing, to me) overhead which not
> much benefit, pragmatic or idealogical. But I could be missing something.
>
> Devin
>
>
>



Gavin Kistner

7/16/2005 4:12:00 AM

0

On Jul 15, 2005, at 6:01 PM, Daniel Brockman wrote:
> The core module Enumerable needs the method `each' to be supplied by
> the user, but doesn't try to get fancy about it. If you supply the
> method, fine; if not, you get an error saying `each' is undefined.

On Jul 15, 2005, at 6:10 PM, Devin Mullins wrote:
> Why? Enumerable requires you to supply #each.

Er...uhm. Good point. Thanks for the head bonk. KISS it is.