Robert Dober
5/6/2007 11:14:00 AM
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