On 06.05.2007 12:49, Robert Klemme wrote:
> On 06.05.2007 10:36, Nanyang Zhan wrote:
>> Forgive me for the nonstandard words. I will describe my problem in
>> details:
>> I am doing a rails app, and met a ruby problem.
>> Inside a model class, I will need to write these codes for "apple"
>> def apple_attr
>>  apples.collect {|o| o.name}.join(" ")
>> end
>>
>> def apple_attr=(str)
>>  @apple = str
>> end
>>
>> def save_apple
>>  #lots of codes
>> end
>>
>> then banana, cat, dog.. each will have a copy of above codes. They are
>> the same, except replacing the word "apple" with "banana", "cat",
>> "dog"....
>>
>> I know there is a way to put these code in to a module, then mixin the
>> module with current class, after that, you just need to call a method
>> (like setup_methods(:apple); setup_methods(:dog)...), instead of typing
>> the repeated code.
>>
>> Would any one tell me how to do it?
> 
> Why not create all the methods on the fly?  Like
> 
> class Foo
>   def setup_methods(sym)
>     cl = class <<self;self;end
>     cl.class_eval do
>       attr_accessor sym
>     end
>     cl.class_eval "def #{sym}_save() puts 'saving #{sym}' end"
>   end
> end
> 
> Now you can do
> 
> irb(main):010:0> f=Foo.new
> => #<Foo:0x7ff74f48>
> irb(main):011:0> f.apple
> NoMethodError: undefined method `apple' for #<Foo:0x7ff74f48>
>         from (irb):11
>         from :0
> irb(main):012:0> f.setup_methods :apple
> => nil
> irb(main):013:0> f.apple
> => nil
> irb(main):014:0> f.apple="foo bar"
> => "foo bar"
> irb(main):015:0> f.apple
> => "foo bar"
> irb(main):016:0> f.apple_save
> saving apple
> => nil
> irb(main):017:0>
> 
> Kind regards
> 
>     robert

PS: of course you can define setup_methods in a module and mixin that 
module.