preventing instantiation

R

R. Mark Volkmann

What is the recommended way in Ruby to prevent other classes from creating
instances of a given class? The class isn't a singleton. It creates several
instances of itself and no additional instances should be able to be created.

I considered making the new method private, but thought there might be a better
way.
 
G

Gavri Fernandez

What is the recommended way in Ruby to prevent other classes from creatin= g
instances of a given class? The class isn't a singleton. It creates sev= eral
instances of itself and no additional instances should be able to be crea= ted.
=20
I considered making the new method private, but thought there might be a = better
way.

What could be a better way than making new private? :)
The simplest solution is the best!

--=20
gavri
http://livejournal.com/users/ga_woo
 
R

R. Mark Volkmann

Quoting Gavri Fernandez said:
What could be a better way than making new private? :)
The simplest solution is the best!

I thought I knew how to do this, but maybe not. These doesn't work.

private :new

private :MyClass.new
 
R

R. Mark Volkmann

Quoting Gavri Fernandez said:
What could be a better way than making new private? :)
The simplest solution is the best!

When I put the following in my class, it seems that even that class can't create
instances.

private_class_method :new

I'm confused. How can I create a few objects within the class and then prevent
other classes from creating additional instances?
 
D

Devin Mullins

Why do you need to strictly enforce instantiation of your objects? Are
you not in a position to implement dependency injection, and let the
container manage instantiation? If not...

R. Mark Volkmann said:
I'm confused. How can I create a few objects within the class and then prevent
other classes from creating additional instances?
class Moo
def initialize
#initialize is an instance method that gets called right after
construction
#by the actual constructor, a predefined class method called 'new'
puts 'created!'
end
end

a = Moo.new
created!
=> #<Moo:0x2acc368>

def make_singleton(aClass)
#use this to define class methods (like new)
class << aClass
def inst
@inst ||= new #method calls don't need parens
end
#meh, i decided I want the existing 'new' method to be private
private :new
end
end

make_singleton(Moo)

b = Moo.new
NoMethodError: private method `new' called for Moo:Class
from (irb):21

b = Moo.inst
created!
=> #<Moo:0x2ab4020>

c = Moo.inst
=> #<Moo:0x2ab4020>
 
S

Steven Jenkins

R. Mark Volkmann said:
When I put the following in my class, it seems that even that class can't create
instances.

private_class_method :new

I'm confused. How can I create a few objects within the class and then prevent
other classes from creating additional instances?

Does this do it?

sjenkins@tidal ~ $ cat t.rb
require 'singleton'

class A; end

a0 = A.new
a1 = A.new
a2 = A.new

class A
include Singleton
end

a3 = A.new
sjenkins@tidal ~ $ ruby t.rb
t.rb:13: private method `new' called for A:Class (NoMethodError)

Remember, 'include' is exectuable.

Steve
 
R

R. Mark Volkmann

Quoting Steven Jenkins said:
Does this do it?

sjenkins@tidal ~ $ cat t.rb
require 'singleton'

class A; end

a0 = A.new
a1 = A.new
a2 = A.new

class A
include Singleton
end

a3 = A.new
sjenkins@tidal ~ $ ruby t.rb
t.rb:13: private method `new' called for A:Class (NoMethodError)

Remember, 'include' is exectuable.

That does work, but I see two issues with that approach.
1) it adds an "instance" method that isn't useful and is misleading
2) someone might think the class is a singleton when in fact it isn't
 
R

R. Mark Volkmann

What is the recommended way in Ruby to prevent other classes from
creating
instances of a given class? The class isn't a singleton. It creates
several
instances of itself and no additional instances should be able to be
created.

When I put the following in my class, it seems that even that class can't
create instances.

private_class_method :new

I'm confused. How can I create a few objects within the class and then
prevent other classes from creating additional instances?

I think I've found the solution I was looking for. I can use

private_class_method :new

I just have to put that line AFTER I create all the instances I want to allow.
 
S

Steven Jenkins

R. Mark Volkmann said:
That does work, but I see two issues with that approach.
1) it adds an "instance" method that isn't useful and is misleading

You can get rid of it, just as you're getting rid of the "new" method
you no longer want.
2) someone might think the class is a singleton when in fact it isn't

Ruby has the '#' construct for just this occasion :)

But I agree, it's not pretty. You advanced quickly from needing *a* way
to finding some ways wanting. :)

Steve
 
G

Gennady Bystritksy

R. Mark Volkmann said:
When I put the following in my class, it seems that even that class can't create
instances.

private_class_method :new

I'm confused. How can I create a few objects within the class and then prevent
other classes from creating additional instances?

When you declare :new private with private_class_method, the class
itself CAN call method "new", as long as it is invoked without self:

class Test
def self.create(*args)
self.new(*args) # does not work
new(*args) # works !!!
end
end

This is because by definition, you cannot specify a receiver when
calling private methods.

Hope this helps,
Gennady.
 
R

R. Mark Volkmann

Quoting Gennady Bystritksy said:
When you declare :new private with private_class_method, the class
itself CAN call method "new", as long as it is invoked without self:

class Test
def self.create(*args)
self.new(*args) # does not work
new(*args) # works !!!
end
end

This is because by definition, you cannot specify a receiver when
calling private methods.

Ah! I didn't know that within a class definition (say Test) you can create
objects with just "new" instead of "Test.new".

Thanks!
 
G

Gennady Bystritksy

R. Mark Volkmann said:
Ah! I didn't know that within a class definition (say Test) you can create
objects with just "new" instead of "Test.new".

Not just within class definition, rather from other class methods (mind
"def self.create", sometimes written as "def Test.create", that starts
definition of class method "create" for class "Test").

You are welcome.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,174
Messages
2,570,940
Members
47,484
Latest member
JackRichard

Latest Threads

Top