David Vallner
2/9/2006 8:15:00 PM
Dna Štvrtok 09 Február 2006 15:33 Une bévue napísal:
> David Vallner <david@vallner.net> wrote:
> > You could possibly golf down your script by having the new Theme object
> > take as constructor parameters the whole old corresponding object, but I
> > don't quite like this sort of coupling of compatibility code in the main
> > logic.
>
> that's a "small" prob to me, i've used java where i might have multiple
> constructors...
>
Constructors are just cleverly disguised initializers. Have #initialize only
do the completely common code, and then explicitly call other initializer
methods you define if you want this pattern. I personally consider method
overloading a slight misfeature of the C++ language family, and have grown
quite accustomed to using the more flexible "options hash" pattern instead.
For example, if you have some class with instance variables bar, baz, and
quux:
class Foo
DEFAULTS = {
:bar => 1,
:baz => 2,
:quux => 3
}
attr :bar
attr :baz
attr :quux
def initialize(params)
attribs = DEFAULTS.dup.update(params)
@bar = attribs[:bar]
@baz = attribs[:baz]
@quux = attribs[:quux]
end
end
foo = Foo.new(:bar = "Hello", :quux => "World")
p foo # Outputs #<Foo:0xb7c8004c @bar="Hello", @quux="World", @baz=2>
I find this covers 90% of what you commonly use overloaded constructors for,
and is a bit more readable too.
> now to workaround i have build an initialize which returns all of its
> attributes to nil or the like ([] in case of arrays)
>
> a defaults method which populate de prefs with default values
>
> an updateFromHash(o) which updates prefs from older structure.
If the above pattern doesn't cover what you need, you can always create more
factory methods to crunch for example the old structure into one the
constructor will like better.
>
> suppose now, in the live of this app, i'll add some new attributes to
> the class Preferences, what is the behaviour of yaml in that case ?
>
> i suppose the new attributes (if an instance of Preferences is loaded
> from older attributes list) will be nill ?
Yes, the YAML loader doesn't know anything about what instance attributes the
object is supposed to have. AFAIK, it uses Object::allocate to create a blank
instance of the class, then populates the instance variables via
Object#instance_variable_set, or something equivalent.