Robert Klemme
10/1/2004 8:01:00 AM
"Bob Sidebotham" <bob@windsong.bc.ca> schrieb im Newsbeitrag
news:c427d.152105$%S.128398@pd7tw2no...
> I would like to define a method that can be used to compactly define
> some items of interest (here called "fields") for subclasses. It's used
> like this:
>
> class B < A
> fields :a, :b, :c
> end
>
> class C < A
> fields :x, :y
> end
>
> p B.new.fields => [:a, :b, :c]
> p C.new.fields => [:x, :y]
>
> Here are two definitions for class A that support these semantics:
>
> ---#1------------------------------------------------
>
> class A
> def self.fields(*fields)
> @fields = fields
> def fields
> self.class.getFields
> end
> end
>
> private
> def self.getFields
> @fields
> end
> end
>
> ---#2------------------------------------------------
>
> class A
> def self.fields(*fields)
> eval "def fields
> [#{fields.collect{|f| ':' + f.to_s}.join(',')}]
> end"
> end
> end
>
> -----------------------------------------------------
>
> Is there a better way (more efficient, shorter and/or clearer) to do
this?
There are numerous alternatives:
class B
attr_accessor :a, :b, :c
end
class B < Struct.new(:a, :b, :c)
end
Also you can use Class#inherited(cl) to do some magic on a sub class. For
an example (not exactly what you want, but you get the picture):
module WithFields
def fields(*a)
@fields = a unless a.empty? ; @fields
end
end
class Base
extend WithFields
def self.inherited(cl)
cl.extend WithFields
def cl.inherited(cl2) superclass.inherited(cl2) end
end
end
class Sub < Base
fields :a, :b, :c
end
class Sub2 < Sub
fields :x, :y
end
p Sub.fields
p Sub2.fields
Kind regards
robert