From: Robert Klemme Date: 2004-03-29T20:54:23+09:00 Subject: Re: YAML and initializers "why the lucky stiff" schrieb im Newsbeitrag news:4067F665.1030500@whytheluckystiff.net... > Good discussion, Hal. I've been really rethinking the YAML+Ruby typing > mechanism, so this is a perfect time for this. Right on. > > Hal Fulton wrote: > > > > When entities have default values in the constructor, we can omit them > > when calling #new. > > > > I'd like to be able to omit these in YAML also. (I can omit them now, > > of course, but they get nil values). > > > > So, if I understand you correctly, you use default values in the > constructor to enforce default values for object properties. In the > case below: > > > > > require "yaml" > > > > class MyClass > > def initialize(a,b,c=5) > > @alpha, @beta, @gamma = a,b,c > > end > > end > > > > ..the use of c=5 is a way of ensuring that 5 is the default value for > @gamma. > > > > > A part of me wishes that YAML could somehow be smart enough to call > > the constructor, maybe with a special call like 'construct' instead > > of 'load' -- but there are likely ramifications I haven't thought of. > > > > In the case of the above constructor, it would be impossible for YAML to > know in what order to pass the three parameters and I don't have any > ideas for making the YAML loader work with the constructor. > > I think the best solution for this would be akin to > Object#initialize_copy. In fact, it seems like YAML could call > Object#initialize_copy with the new object, should an > Object#initialize_copy method exist. Yeh? > > Yes, you can also do this with a typing callback: > > YAML::add_domain_type( "hypermetrics.com,2004", "MyClass" ) do > |type, val| > val['gamma'] ||= 5 > YAML::object_maker( MyClass, val ) > end > > YAML::load( < --- !hypermetrics.com,2004/MyClass > alpha: 10 > beta: 20 > EOY > #=> # As food for thought: This could be extended into something more general: class MyClass DEFAULTS = {:gamma => 5} def initialize(a,b,c=DEFAULTS[:gamma]) @alpha, @beta, @gamma = a,b,c end end YAML::add_domain_type( "hypermetrics.com,2004", "MyClass" ) do |type, val| scheme, domain, name = type.split(/:/) t = Object.const_get name if t.const_defined? :DEFAULTS t::DEFAULTS.each do |sym, v| val[sym.to_s] ||= v end end YAML::object_maker( t, val ) end YAML::load( <