Preventing instantiation

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.

···

--
R. Mark Volkmann
Partner, Object Computing, Inc.

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

···

On 6/19/05, R. Mark Volkmann <mark@ociweb.com> wrote:

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.

--
gavri

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? :slight_smile:
The simplest solution is the best!

In addition, look at the multiton library:
http://raa.ruby-lang.org/project/multiton/

HTH,
Assaph

Quoting Gavri Fernandez <gavri.fernandez@gmail.com>:

···

On 6/19/05, R. Mark Volkmann <mark@ociweb.com> wrote:
> 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.

What could be a better way than making new private? :slight_smile:
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. Mark Volkmann
Partner, Object Computing, Inc.

Quoting Gavri Fernandez <gavri.fernandez@gmail.com>:

···

On 6/19/05, R. Mark Volkmann <mark@ociweb.com> wrote:
> 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.

What could be a better way than making new private? :slight_smile:
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?

--
R. Mark Volkmann
Partner, Object Computing, Inc.

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 wrote:

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>

R. Mark Volkmann wrote:

Quoting Gavri Fernandez <gavri.fernandez@gmail.com>:

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.

What could be a better way than making new private? :slight_smile:
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?

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

···

On 6/19/05, R. Mark Volkmann <mark@ociweb.com> wrote:

R. Mark Volkmann wrote:

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?

--
R. Mark Volkmann
Partner, Object Computing, Inc.

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.

Quoting Steven Jenkins <steven.jenkins@ieee.org>:

···

>>On 6/19/05, R. Mark Volkmann <mark@ociweb.com> wrote:
>>
>>>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?

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. Mark Volkmann
Partner, Object Computing, Inc.

Quoting Gennady Bystritksy <gfb@tonesoft.com>:

R. Mark Volkmann wrote:

>
> 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.

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

Thanks!

···

--
R. Mark Volkmann
Partner, Object Computing, Inc.

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.

···

On 6/19/05, R. Mark Volkmann <mark@ociweb.com> wrote:

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?

--
R. Mark Volkmann
Partner, Object Computing, Inc.

R. Mark Volkmann wrote:

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 :slight_smile:

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

Steve

R. Mark Volkmann wrote:

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".

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").

Thanks!

You are welcome.

···

--
R. Mark Volkmann
Partner, Object Computing, Inc.