[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Named Constructor Idiom in Ruby?

Arlen Cuss

8/18/2007 1:36:00 PM

Hi all,

I'm almost certain there's a good way to do this, but I seem to have
lost hold of the thought of how -- is there a straight-forward/neat way
to do the named constructor idiom in Ruby?

In C++ terms, a class like this implements it:

class A {
public:
static A something() {
A a;
// do something special to a
return a;
}

static A otherthing() {
A a;
// some other special thing to a
return a;
}

protected:
A();
};

The result is that we can't construct A directly, only by one of the two
'named' constructors. Is there any way to achieve a similar thing using
protection in Ruby?

Thanks,

Arlen.


5 Answers

Stefan Rusterholz

8/18/2007 1:42:00 PM

0

Arlen Christian Mart Cuss wrote:
> Hi all,
>
> I'm almost certain there's a good way to do this, but I seem to have
> lost hold of the thought of how -- is there a straight-forward/neat way
> to do the named constructor idiom in Ruby?
>
> In C++ terms, a class like this implements it:
>
> class A {
> public:
> static A something() {
> A a;
> // do something special to a
> return a;
> }
>
> static A otherthing() {
> A a;
> // some other special thing to a
> return a;
> }
>
> protected:
> A();
> };
>
> The result is that we can't construct A directly, only by one of the two
> 'named' constructors. Is there any way to achieve a similar thing using
> protection in Ruby?
>
> Thanks,
>
> Arlen.

I think you want something like this:
# somewhat contrieved example
class Clock
class <<self
private :new
def from_string(string)
new(*string.match(SomeRegexp).captures)
end
def from_seconds(int)
new(int)
end
end
end

HTH

regards
Stefan
--
Posted via http://www.ruby-....

Stefano Crocco

8/18/2007 1:42:00 PM

0

Alle sabato 18 agosto 2007, Arlen Christian Mart Cuss ha scritto:
> Hi all,
>
> I'm almost certain there's a good way to do this, but I seem to have
> lost hold of the thought of how -- is there a straight-forward/neat way
> to do the named constructor idiom in Ruby?
>
> In C++ terms, a class like this implements it:
>
> class A {
> public:
> static A something() {
> A a;
> // do something special to a
> return a;
> }
>
> static A otherthing() {
> A a;
> // some other special thing to a
> return a;
> }
>
> protected:
> A();
> };
>
> The result is that we can't construct A directly, only by one of the two
> 'named' constructors. Is there any way to achieve a similar thing using
> protection in Ruby?
>
> Thanks,
>
> Arlen.

You need to make the new class method of class A private. Then, you implement
the class methods you want to make public to create the instances of A:

class A

private_class_method :new

def self.special_method_1
a = A.new
#do something special
a
end

def self.special_method_2
a = A.new
#do something else special
a
end

end

a1 = A.special_method1
a2 = A.special_method2

I hope this helps

Stefano

Arlen Cuss

8/18/2007 1:56:00 PM

0


Exactly what I needed, both Stefan and Stefano! Thanks very much. :)

Cheers,
Arlen.


Robert Klemme

8/20/2007 8:43:00 AM

0

2007/8/18, Stefano Crocco <stefano.crocco@alice.it>:
> Alle sabato 18 agosto 2007, Arlen Christian Mart Cuss ha scritto:
> > Hi all,
> >
> > I'm almost certain there's a good way to do this, but I seem to have
> > lost hold of the thought of how -- is there a straight-forward/neat way
> > to do the named constructor idiom in Ruby?
> >
> > In C++ terms, a class like this implements it:
> >
> > class A {
> > public:
> > static A something() {
> > A a;
> > // do something special to a
> > return a;
> > }
> >
> > static A otherthing() {
> > A a;
> > // some other special thing to a
> > return a;
> > }
> >
> > protected:
> > A();
> > };
> >
> > The result is that we can't construct A directly, only by one of the two
> > 'named' constructors. Is there any way to achieve a similar thing using
> > protection in Ruby?
> >
> > Thanks,
> >
> > Arlen.
>
> You need to make the new class method of class A private. Then, you implement
> the class methods you want to make public to create the instances of A:
>
> class A
>
> private_class_method :new
>
> def self.special_method_1
> a = A.new
> #do something special
> a
> end
>
> def self.special_method_2
> a = A.new
> #do something else special
> a
> end
>
> end
>
> a1 = A.special_method1
> a2 = A.special_method2
>
> I hope this helps

A small glitch:

irb(main):020:0> a1 = A.special_method_1
NoMethodError: private method `new' called for A:Class
from (irb):6:in `special_method_1'
from (irb):20
from :0

You need to remove the "A." when calling "new" after making it
private. It's not needed anyway.

irb(main):021:0> def A.special_method_1
irb(main):022:1> a=new
irb(main):023:1> a
irb(main):024:1> end
=> nil
irb(main):025:0> a1 = A.special_method_1
=> #<A:0x7ff63428>

Kind regards

robert

Daniel Lucraft

8/20/2007 9:57:00 AM

0

Arlen Christian Mart Cuss wrote:
> lost hold of the thought of how -- is there a straight-forward/neat way
> to do the named constructor idiom in Ruby?

You have some good answers, but here is yet another way that is quite
interesting:

class A
class << self; private :new; end

def self.something
a = self.allocate
# set up a somehow
a
end

def self.otherthing
a = self.allocate
# set up a somehow
a
end
end

allocate is like new but without calling initialize. I believe that new
is basically defined as: (1) allocate, (2) initialize.

The only benefit of this over the other solutions is that it avoids
calling new altogether. I have found this useful in a case where the new
was very generalized and therefore slow.

best,
Dan
--
Posted via http://www.ruby-....