Named Constructor Idiom in Ruby?

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.

Alle sabato 18 agosto 2007, Arlen Christian Mart C. ha scritto:

static A something() {

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 Christian Mart C. 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

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

Cheers,
Arlen.

2007/8/18, Stefano C. [email protected]:

public:
}

a = A.new

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

Arlen Christian Mart C. 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