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