PDA

View Full Version : Unclear 'Programming Ruby' section



Caduceus
April 18th, 2008, 01:47 PM
I've spent nearly 30 minutes trying to decipher this:


class MyLogger
private_class_method :new
@@logger = nil

def MyLogger.create
@@logger = new unless @@logger
return @@logger
end
end

I understand private_class_method (that's self-explanatory), but can anyone walk me through the class line-by-line and tell me what it does and why? The explanation in the book isn't clear (I'll post it if need be).

mssever
April 18th, 2008, 04:27 PM
This is similar to the official documentation:
ri private_class_method
If for some reason you wanted to prevent people from calling YourClass.new, you'd use this. You'd of course need a method that people could call to get a new instance.

This particular class ensures that there is only ever one instance of MyLogger. If there isn't one yet, MyLogger.create creates and returns a new one. If one does exist, then MyLogger.create returns the existing instance.

Caduceus
April 18th, 2008, 04:35 PM
Thanks, I can finally move on now I'm sure on what it means!

geraldm
April 18th, 2008, 11:13 PM
As it stands, it is non-working code.

Every attempt to create a new class instance fails as it is written, because @@logger is assigned nil before new is called, and it must be non-nil to allow new to be performed the first time.

There should be other methods to have a working class code.

Gerald

skeeterbug
April 19th, 2008, 12:23 AM
FYI this is the singleton design pattern (if the book didn't already mentioned it). Read more about it here:

http://en.wikipedia.org/wiki/Singleton_pattern

mssever
April 19th, 2008, 03:11 AM
As it stands, it is non-working code.

Every attempt to create a new class instance fails as it is written, because @@logger is assigned nil before new is called, and it must be non-nil to allow new to be performed the first time.

There should be other methods to have a working class code.
Did you test it? It DOES work. I just ran it as written. There's nothing wrong with @@logger being nil to begin with. The first time MyLogger.create is called, an instance is created and assigned to @@logger. There's nothing wrong with the code.

EDIT: FWIW, the similar class given in the ri doc for private_class_method warns that this approach isn't threadsafe.

crush304
April 19th, 2008, 04:16 AM
iirc @@ is used for a class variable (it is the same in every instance of the class)

the example code blocks you from using the new method to initialize a class and forces you to use the create method

the first time you call create, it calls the new method, all other times it returns the class you created the first time

for example


class MyLogger
private_class_method :new
@@logger = nil

def MyLogger.create
@@logger = new unless @@logger
return @@logger
end
end

a=MyLogger.create
b=MyLogger.create

puts a.to_s
puts b.to_s

results in


#<MyLogger:0x2ae17098a018>
#<MyLogger:0x2ae17098a018>


a and b are the same

Caduceus
April 19th, 2008, 08:22 AM
skeeterbug - It says that in the book, yes. It also mentions the built-in Singleton pattern.

mssever - It says in small print it's not thread safe, yes.

Thanks for the replies everyone!