Common constructor idioms

In C++ one often declares a constructor that accepts another instance
of this class. For those familiar with C++ syntax I’m talking about:

class MyClass {
/* other interesting stuff in this class deleted */

/* Copy constructor */
MyClass(const MyClass &objectToCopy);

};

I guess you could do something similar in Ruby like this:

class MyClass
def initialize(x)
if x.class == MyClass then
#some code to duplicate stuff in x
else
#potentially other initialization mechanisms here
end
end
end

Though there are bound to be differing opinions on the subject (and I
have no desire to start a flame war so please be kind) I was curious to
know is a popular idiom in Ruby code or not? More to the point, would
someone who was using an Ruby extension reasonably assume that this
initialization mechanism was included?

Scott

Hi,

···

In message “common constructor idioms” on 03/08/13, Scott Thompson easco@mac.com writes:

In C++ one often declares a constructor that accepts another instance
of this class. For those familiar with C++ syntax I’m talking about:

class MyClass {
/* other interesting stuff in this class deleted */

/* Copy constructor */
MyClass(const MyClass &objectToCopy);
};

I guess you could do something similar in Ruby like this:

class MyClass
def initialize(x)
if x.class == MyClass then
#some code to duplicate stuff in x
else
#potentially other initialization mechanisms here
end
end
end

How about leaving “initialize” for basic initialization, and define
class methods for each object construction scheme, with proper names?

						matz.

Scott Thompson said:

Though there are bound to be differing opinions on the subject (and I
have no desire to start a flame war so please be kind) I was curious to
know is a popular idiom in Ruby code or not? More to the point, would
someone who was using an Ruby extension reasonably assume that this
initialization mechanism was included?

That would work, but I’d suspect that it isn’t popular around these parts.
I would also suggest that it’s probably not safe to assume that type of
initialization system is included with any given extension…

It would be a much clearer implementation to specifically define a
deep_copy method in your class, a la:

def deep_copy
Marshal.load(Marshal.dump(self))
end

Of course, if you don’t need a deep copy, you’ve already got
Object.clone… someone smack me if I’m way off base here. :slight_smile:

-Ryan

···


Ryan Dlugosz
ryan@dlugosz.net

http://dlugosz.net

Scott Thompson wrote:

In C++ one often declares a constructor that accepts another instance of
this class. For those familiar with C++ syntax I’m talking about:

class MyClass {
/* other interesting stuff in this class deleted */

/* Copy constructor */
MyClass(const MyClass &objectToCopy);

};

I guess you could do something similar in Ruby like this:

class MyClass
def initialize(x)
if x.class == MyClass then
#some code to duplicate stuff in x
else
#potentially other initialization mechanisms here
end
end
end

Though there are bound to be differing opinions on the subject (and I
have no desire to start a flame war so please be kind) I was curious to
know is a popular idiom in Ruby code or not? More to the point, would
someone who was using an Ruby extension reasonably assume that this
initialization mechanism was included?

Personally I wouldn’t overload #new like this. Instead I’d add a new
static construction method

 class Boat
    def Boat.from_other_boat(b)
       # ...
    end
 end

…or… I’d simply implement an instance method to duplicate a
particular object.

I wrote a blog entry on constructors:

http://pragprog.com/pragdave/Practices/ConstructionMethods.rdoc,v

Cheers

Dave

How about leaving “initialize” for basic initialization, and define
class methods for each object construction scheme, with proper names?

  					matz.

Ok. I can do that too. :slight_smile:

Scott

Using the following code segment…

···

require ‘Win32API’

$shellExecute = Win32API.new( “shell32”, “ShellExecute”,
[‘L’,‘P’,‘P’,‘P’,‘P’,‘L’], ‘L’)

objs = Hash.new(0)

ObjectSpace.each_object { |o| objs[o.class] += 1 }

objs.sort{|x,y| y[1] <=> x[1]}.each { |k,v|
p “#{k}=#{v}”
}

I get a bug segmentation fault on the ObjectSpace.new line.

Comment out the shellexecute line and it runs normally.

I looked at the win32api code and noted that there was no
call to rb_define_alloc_func

Is this required ( I compared it to win32ole )?

I couldn’t find documentation on rb_define_alloc_func in readme.ext

Anyone?

class MyClass
def initialize(x)
if x.class == MyClass then
#some code to duplicate stuff in x
else
#potentially other initialization mechanisms here
end
end
end

[snip]

…or… I’d simply implement an instance method to duplicate a
particular object.

Or just implement the copy constructor and use #dup or #clone:

class MyClass
def initialize_copy( x )
# Some code to duplicate stuff in x
end
end

···

On Tuesday, August 12, 2003, at 11:49 AM, Dave Thomas wrote:


Michael Granger ged@FaerieMUD.org
Rubymage, Believer, Architect
The FaerieMUD Consortium http://www.FaerieMUD.org/

By the way, I confirmed the behavior on 1.6.8 aqnd 1.8.0

···

-----Original Message-----
From: Allen Mitchell [mailto:ajm@nb.sympatico.ca]
Sent: August 12, 2003 10:04 PM
To: ruby-talk ML
Subject: BUG in Win32API

Using the following code segment…


require ‘Win32API’

$shellExecute = Win32API.new( “shell32”, “ShellExecute”,
[‘L’,‘P’,‘P’,‘P’,‘P’,‘L’], ‘L’)

objs = Hash.new(0)

ObjectSpace.each_object { |o| objs[o.class] += 1 }

objs.sort{|x,y| y[1] <=> x[1]}.each { |k,v|
p “#{k}=#{v}”
}

I get a bug segmentation fault on the ObjectSpace.new line.

Comment out the shellexecute line and it runs normally.

I looked at the win32api code and noted that there was no
call to rb_define_alloc_func

Is this required ( I compared it to win32ole )?

I couldn’t find documentation on rb_define_alloc_func in readme.ext

Anyone?