The attached code prints: print g1 locks 5 print g2 locks 5 3 I would expect g2 to print 3. Why the Lock object behaves like singleton? Thanks. Javier.
on 2012-11-27 17:00
on 2012-11-27 17:20
Hi, a class variable (in your case @@locks) is shared among the class and all instances of the class -- as well as all subclasses and their instances. So when g1 or g2 do something with @@locks, it's always the same array. I think you generally misunderstand the difference between the various types of variables. For example, the variable @lock in @lock = 0 is completely different from the one you use in the initialize method, and in your case it's simply useless. Ruby is not Java where this syntax is used to set default values. So you might wanna read up on this topic: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes You should generally avoid class variables unless you really know what you're doing. Use instance variables or class instance variables depending on the specific purpose. To fix your code, replace @@locks with an instance variable and set it in the correct context: ---------------------------- class Locks def initialize ( rd ) @locks = [] rd.each do |k| @locks << Lock.new(rd) end end def printLocks @locks.each do |l| puts l.glock() end end end ----------------------------
on 2012-11-27 17:21
On Tue, Nov 27, 2012 at 5:00 PM, Javier Isassi <lists@ruby-forum.com>
wrote:
> like singleton?
class Lock
@lock = 0
# This variable is not the same as the one used below in initialize
and glock methods. The reason is that @xxx refers to an instance
variable of the object that happens to be self in that scope, and in
this case the object is the Lock class itself, while in the initialize
and glock methods, it's a specific instance of the Lock class. So, in
summary, you can remove this line.
def initialize(r)
@lock = r
end
def glock()
@lock
end
end
class Locks
@@locks = []
# A variable prefixed with @@ is a class variable. It is shared among
the class and all its subclasses. Every reference to this variable in
this scope or in instance methods of this class or any subclass will
refer to the same object. You most certainly don't want this. So
remove this and change it with @locks = [] inside the initialize
method, which creates an instance variable of the object being
initialized.
def initialize ( rd )
rd.each do |k|
@@locks << Lock.new(rd)
end
end
def printLocks
@@locks.each do |l|
puts l.glock()
end
end
end
I would try:
class Lock
attr_reader :lock
def initialize r
@lock = r
end
end
class Locks
def initialize lock_ids
@locks = []
lock_ids.each {|id| @locks << Lock.new(id)}
end
def print_locks
@locks.each {|lock| puts lock.lock}
end
end
1.9.2p290 :019 > g1 = Locks.new([5])
=> #<Locks:0x00000001744568 @locks=[#<Lock:0x00000001744518 @lock=5>]>
1.9.2p290 :020 > puts "print g1 locks"
print g1 locks
=> nil
1.9.2p290 :021 > g1.print_locks
5
=> [#<Lock:0x00000001744518 @lock=5>]
1.9.2p290 :022 > g2 = Locks.new([3])
=> #<Locks:0x0000000174fc38 @locks=[#<Lock:0x0000000174fbe8 @lock=3>]>
1.9.2p290 :023 > puts "print g2 locks"
print g2 locks
=> nil
1.9.2p290 :024 > g2.print_locks
3
Jesus.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.