private #initialize

Y

Yossef Mendelssohn

My apologies if this has been discussed before, but I couldn't find
anything in a Google search, searching this particular list/group on
Google, or my first attempt at blade. (Later attempts complained about
not being able to access the index.)

So, in Ruby a private method is one that can only be called by the
object itself, and that's enforced by the simple rule of disallowing
an explicit receiver. Of course, there are ways around this; any
message can be passed if you just know what to do. Maybe I'm late to
the game, but I didn't realize it was okay to have #initialize be a
private method. More than that, I didn't realize #initialize was
*always* private. This confuses me because I think of SomeClass.new to
be

def new(*args, &block)
instance = allocate
instance.initialize(*args, &block)
instance
end

But that obviously can't be the case if #initialize is private.
Instead, it has to be

def new(*args, &block)
instance = allocate
instance.send:)initialize, *args, &block)
instance
end

It's a small change, but significant. And it seems odd to have
something this central to the language skirting the boundaries of
access control. Is it simply because an object shouldn't be re-
initialized once it's created? And if so, is that so horrible?
 
W

Wayne Vucenic

Is it simply because an object shouldn't be re-
initialized once it's created? And if so, is that so horrible?

I don't think the issue is that an object shouldn't be re-initialized, I think
it's that (in general) an object shouldn't be re-initialized by anyone
except itself. If I'm writing a class, I'll declare certain instance methods
private, because I don't want clients calling them. initialize seems like
a method that I rarely want clients to be able to call.

Best regards,

Wayne
 
R

Robert Dober

#initialize is, by its design, supposed to be called only from within
#new to separate per object/class initialization from the #new, thus
you don't have to redefine #new. When you need/want to redefine #new,
it's a sign of a bad design, I believe.
I am delivering this code to your judgment

module Immutable
def new *args, &blk
o =3D allocate
o.send( :initialize, *args, &blk )
o.freeze
end
end
One of the reason #initialize being private is to tell you bad design.

I can not come up with a better design as the above. But I am
listening of course.
Calling freeze on self at the end of #initialize is really asking for
trouble with subclasses.

Now that all said, it is good that #initialize is private because it
makes you think before doing tricky things as above
but I would not call it bad design.

Cheers
Robert

--=20
Ne baisse jamais la t=EAte, tu ne verrais plus les =E9toiles.

Robert Dober ;)
 
M

Michael Neumann

Robert said:
I am delivering this code to your judgment

module Immutable
def new *args, &blk
o = allocate
o.send( :initialize, *args, &blk )
o.freeze
end
end

How about this?

module Immutable
def new(*args, &blk)
super.freeze
end
end

Okay, this will not work if you redefine #new yourself. Or that?

module Immutable
def self.included(klass)
class << klass
alias __old_new new
def new(*args, &blk)
__old_new(*args, &blk).freeze
end
end
end
end

(will not work when including into a module)

Regards,

Michael
 
S

Stefan Rusterholz

Michael said:
How about this?
module Immutable
def self.included(klass)
class << klass
alias __old_new new
def new(*args, &blk)
__old_new(*args, &blk).freeze
end
end
end
end

Wrong hook. new is a class method, so you'll want to extend, so def
self.extended.

Regards
Stefan Rusterholz
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top