On May 10, 2008, at 6:40 PM, David A. Black wrote:
have a copy of the object? If so, I would just do:
That gives the results you expect in your test.
careful, any ruby code that uses ‘dup’ or clone has serious bugs 9 out
of 10 times, in the case it doesn’t meet the OP’s requirements
(although the simple test case passes) at all:
cfp:~ > cat a.rb
doesn’t let instance modify the var without modifying the class var
Tester.add_var ‘oops’
t = Tester.new
t.vars.first << ‘, this modifies the original’
p Tester.vars #=> “oops, this modifies the original”
and doesn’t take a copy either
Tester.vars.clear
Tester.add_var [‘oops’]
t = Tester.new
t.vars.first << ‘, this modifies the original’
p Tester.vars #=> [[“oops”, “, this modifies the original”]]
BEGIN {
class Tester
def self.vars
@vars ||= []
end
def self.add_var(var)
self.vars << var
end
def vars
@vars || self.class.vars
end
def add_var(var)
@vars ||= self.class.vars.dup
vars << var
end
end
}
cfp:~ > ruby a.rb
[“oops, this modifies the original”]
[[“oops”, “, this modifies the original”]]
you really need one of two things: a factory or a smarter copy
algorithm:
using a factory:
cfp:~ > cat a.rb
class Shares
Factory = lambda { |var|
case var.to_s
when ‘a’
‘not shared’
when ‘b’
‘but created fresh for class and instance cases’
else
end
}
def Shares.a
@a ||= Factory[‘a’]
end
def a
@a ||= Factory[‘a’]
end
end
p Shares.a
shares = Shares.new
shares.a << “, but it’s own copy”
p Shares.a
p shares.a
cfp:~ > ruby a.rb
“not shared”
“not shared”
“not shared, but it’s own copy”
or, using a smart copy method:
cfp:~ > cat a.rb
class Shares
def Shares.a
@a ||= ‘not shared’
end
def a
@a ||= Marshal.load(Marshal.dump(Shares.a))
end
end
p Shares.a
shares = Shares.new
shares.a << “, but it’s own copy”
p Shares.a
p shares.a
cfp:~ > ruby a.rb
“not shared”
“not shared”
“not shared, but it’s own copy”
this is nicer, but only works for objects you can marshal - obvisouly.
a @ http://codeforpeople.com/