Ruby Idiom: two alternate constructors on a Value Object

L

listrecv

I'm having trouble discovering the correct Ruby idiom for this:

I know how to create a second constructor:

def self.from_address(address)

But, how can that constructor call private methods on the object?
I hate to force methods needed by that constructor to be public, just
so it can use it. Is there any solution?
 
T

Timothy Goddard

You can use instance_eval to execute a block in the context of an
object. This will allow you to call private methods.
 
G

gabriele renzi

Timothy Goddard ha scritto:
You can use instance_eval to execute a block in the context of an
object. This will allow you to call private methods.

or you can just use
object.send :privatemethodname, arg1, arg2, argN
 
D

Dave Burt

gabriele said:
Timothy Goddard ha scritto:

or you can just use
object.send :privatemethodname, arg1, arg2, argN

Isn't that (using send to call a private method) deprecated?

Dave
 
T

ts

D> Isn't that (using send to call a private method) deprecated?

It's called #funcall in 1.9

moulon% ./ruby -ve 'self.send:)puts, "a")'
ruby 1.9.0 (2006-06-20) [i686-linux]
-e:1:in `BasicObject#send': private method `puts' called for main:Object (NoMethodError)
from -e:1
moulon%

moulon% ./ruby -ve 'self.funcall:)puts, "a")'
ruby 1.9.0 (2006-06-20) [i686-linux]
a
moulon%
 
L

listrecv

All these techniques are hackish, in that you need to set up an access
control means and break it.

Is there no way to mark a method as "may be called by the instance as
well as by class methods"?
 
A

Austin Ziegler

All these techniques are hackish, in that you need to set up an access
control means and break it.

Is there no way to mark a method as "may be called by the instance as
well as by class methods"?

No. Because "class methods" aren't what you think they are.

You could have a flag in your class that would prevent the calling of
the initialization method more than once.

-austin
 
Z

zycte

No. Because "class methods" aren't what you think they are.

To be more specific, a class is just an object, which also follows
normal access control (public: everyone, private: me only, protected:
descendants)

Although this is very consequent, it makes it sometimes a pain, like in
your example. I also ran into this issue a while ago, I decided just to
go public with one helper initializer and by documenting it as private
in the API.
 
L

listrecv

I think it is an issue of implenetation versus intention.

Implementation wise, it makes sense. Class methods aren't to be viewed
as static methods of the class - they're methods of a different class,
of class Class.

Intention wise - it seems wrong to me. I should be able to mark
methods as not being part of the public interface, but usable in
constructors and other "static" methods.

Reminds me of the ol' Unix
you-can-delete-a-file-that-you-don't-have-write-permissions-to paradox.
Looking at the implementation, you can understand this (deleting a
file is not writing to it but rather to its directory). Intention
wise, it's wrong. What surprises me is that Ruby seems to go with the
OO theme of focusing on intention, not implementation.

My 2 cents.
 

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

Forum statistics

Threads
474,208
Messages
2,571,080
Members
47,682
Latest member
TrudiConna

Latest Threads

Top