From: Mark Probert Date: 2002-02-23T04:52:14+09:00 Subject: Re: dispatching and class references At 04:24 AM 2/23/2002 +0900, Paul B. wrote: > > > > It seems that ruby returns object values by reference. > > Is there any way to return the value? I would like the > > pattern, stored in Sym::val to be treated as a template > > and retain its value ('xxx') over each dispatch call. > >Returning by value is almost the same as returning a reference to a >copy. > >To make a smallow copy: > obj.dup > >To make a deep copy: > Marshal::load(Marshall::dump(obj)) > >Returning copies will have a performance impact. If you want to return >a reference but still not allow the user to change the returned object, >you can return a frozen object. Now I -am- confused! :-) I have added 'freeze' to the Sym.new() call, and ruby says the object is frozen. However, I can still modify the returned object val. The same happens if I .dup() the dispatch method. The manual states: "[freeze] Prevents further modifications to obj. A TypeError will be raised if modification is attempted." I don't really know what is going here -- I would have thought that freeze would stop modifications to the object, or modification to the contents of the object. I guess that it doesn't! class Sym attr_reader :sym, :val def initialize(sym, val) @sym = sym @val = val end def to_s "sym = #{@sym} val=#{@val}" end end class Bob @@dtbl = { 'a' => Sym.new(:do_a, 'this is a string: xxx').freeze, 'b' => Sym.new(:do_b, 'so is this: xxx').freeze } def do_a(msg=nil) puts "a --> #{msg}" end def do_b(msg=nil) puts "b --> #{msg}" end def dispatch(ref=nil) if @@dtbl[ref] obj = @@dtbl[ref] s = obj.val s.sub!(/xxx/, '123') send obj.sym, obj.val else puts "--> unknown ref (#{ref})" end end def prntbl @@dtbl.keys.each do |k| puts @@dtbl[k] puts " --> frozen" if @@dtbl[k].frozen? end end end irb(main):001:0> b = Bob.new # irb(main):002:0> b.prntbl sym = do_a val=this is a string: xxx --> frozen sym = do_b val=so is this: xxx --> frozen ["a", "b"] irb(main):003:0> b.dispatch('a') a --> this is a string: 123 nil irb(main):004:0> b.prntbl sym = do_a val=this is a string: 123 --> frozen sym = do_b val=so is this: xxx --> frozen ["a", "b"] >Paul -mark ----- Mark Probert GNPS - Optera Metro 3000 Tel (613) 768-1082 (ESN: 398-1082) Mob (613) 715-2045 email: probertm@nortelnetworks.com