On 5/6/07, Robert Klemme <shortcutter / googlemail.com> 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
Robert I have understood the setup a little bit differently, was it
not on the class base that OP wanted his methods?

Your technique of course is correct, just that - if I were right - OP
needed this

class Foo

   %w{ apple banana mango strawberry }.each do
        |fruit|
        define_method "#{fruit}_attr" do
            send(fruit.pluralize).map{|f|f.name}.join(",")
        end
        define_method "#{fruit}_attr=" do
           | str |
           instance_variable_set("@" << fruit, str)
        end
        define_method "save_" << fruit do
          # lots of code adapted to metaprogramming, which might be possible :)
          # or not :(
        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
>
>

f = Foo.new # has methods like apples_attr, save_strawberry and
banana_attr= already, which might make sense or not

HTH
Robert
-- 
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw