From: ara.t.howard@... Date: 2006-06-02T00:27:32+09:00 Subject: Re: An alternative to the class Foo < Struct.new(vars) idiom and SuperStruct On Thu, 1 Jun 2006, Mauricio Fernandez wrote: hi mauricio- thought i'd just chime in here and show how this would be done with traits since it has overlapping aims: > class MyClass < SuperClass.new(:a, :b) # doubly appropriate :) > def sum > @a + @b > end > end > a = MyClass.new(1, 1) > a # => # > a.sum # => 2 > > The generated class uses normal instance variables unlike Struct.new, and > creates the accessors for you. > > You also get keyword arguments for free: > > b = MyClass.new :a => 1, :b => 41 > b.sum # => 42 > b # => # > b.b # => 41 harp:~ > cat a.rb require 'traits' class MyClass include TraitInit trait_initialize 'a', 'b' def sum() a + b end end a = MyClass.new 40, 2 p a.a p a.b p a.sum a = MyClass.new 'b' => 2, 'a' => 40 p a.a p a.b p a.sum p MyClass.traits harp:~ > ruby a.rb 40 2 42 40 2 42 [["a", "a="], ["b", "b="]] > Default values are handled as follows: > > class Foo < SuperClass.new(:text, :times) { @times ||= 2 } > def greeting > (["Hello, #{@text}"] * times).join("\n") > end > end > > Foo.new("SuperClass", 2).greeting # => "Hello, SuperClass\nHello, SuperClass" > Foo.new(:text => "world").greeting # => "Hello, world\nHello, world" harp:~ > cat a.rb require 'traits' class MyClass include TraitInit trait_initialize 'a' => 40, 'b' => 2 def sum() a + b end end class MyClass2 < MyClass; end p MyClass.new.sum p MyClass2.new.sum harp:~ > ruby a.rb 42 42 note that it works with inheritence too. > Unlike Struct.new, you can use SuperClass to generate classes in the middle > of the inheritance chain: > > class X > attr_reader :foo > def initialize(foo = 1) > @foo = foo > end > end > > class Y < SuperClass.new(:bar, :baz, X) {@baz ||= 10; initialize_super(@baz + 1) } > def fubar; @foo + @baz end > end > > Y.new(10, 1).foo # => 2 > Y.new(:bar => 1).fubar # => 21 harp:~ > cat a.rb require 'traits' class X include TraitInit trait_initialize trait :foo => 1 end class Y < X trait :bar, :baz => 10 trait(:foo){ baz + 1 } def fubar() foo + baz end end p Y.new(:bar => 10, :baz => 1).foo p Y.new(:bar => 1).fubar harp:~ > ruby a.rb 2 21 traits is here if anyone is interested http://rubyforge.org/projects/codeforpeople/ http://codeforpeople.com/lib/ruby/traits kind regards. -a -- be kind whenever possible... it is always possible. - h.h. the 14th dali lama