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

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs