Private visibility should be removed from Ruby 2 [was: Caveats with #method_missing]

  • Thread starter Tomasz Wegrzanowski
  • Start date
T

Tomasz Wegrzanowski

NoMethodError: protected method `sortable' called for #<struct Name
first="foo", last="bar">
from (irb):23
from (irb):23
from :0

So why doesn't a.instance_eval { self.sortable } work ?
I stand by my statement that pretty much nobody understands "protected".
 
J

James Edward Gray II

So why doesn't a.instance_eval { self.sortable } work ?
I stand by my statement that pretty much nobody understands
"protected".

Because that's a method call, not a function-style call.

James Edward Gray II
 
V

Vidar Hokstad

Tomasz said:
Now imagine a C++ object. It is not a black box at all. It has
*multiple interfaces*, and everything that communicates with it must
know *exactly* what at least some of them are. Like with Smalltalk
object, it receives messages. But the sender addresses messages to
different interfaces, not to the object itself. So one message "bar"
can be sent to "Foo in public context", while other message "bar" can
be sent to "Bar in private context". It is pretty meaningless to talk
about "sending messages to objects" in C++, as the receiver is not an
object (but one of its many interfaces) and the message must know
exactly what interface it is targetting.

Indeed, C++ doesn't purport to have messages or methods. The C++
specification on purpose use the term "member functions". The "message"
does not need to know what interface it is targetting - the caller
needs to know that it is satisfying all the restrictions that the
function signature and class of the object.

However to call it different interfaces is misleading too - it is a
single interface, but the interface specifies pre-conditions that must
be satisfied before you are allowed to use it. . Private/protected is
only part of that - the types of the arguments are also part of it. Yet
I assume you wouldn't claim it has multiple arguments because it acts
differently if you try to pass a string instead of an integer to the
same function? Even Ruby has pre-conditions that must be met before a
method call can be successfully completed.

One difference is that in C++ a larger set of those pre-conditions are
enforced by the compiler as part of type checking up front, whereas in
Ruby more is left up to the developer, or will result in failures
during testing instead. The other is that C++ mentality is very much to
use the compiler to enforce design: Make compilation fail if the client
of a piece of code tries to do something he/she shouldn't, such as
calling member functions that are meant for internal use only. A lot of
work on C++ meta-programming focus on adding more restrictions to push
failures forward to compile time to limit the problem space that needs
to be covered for testing, and to limit needs for runtime checks.

I think it's unfair to say that this means C++ objects are not black
box. If anything, they are more so: The typical design aim is to narrow
the interface as much as possible. private/public/protected specifiers
are tools to achieve that, exactly in order to ensure that not only
attributes, but also member functions not meant for public use gets
hidden from clients. Hiding the interface doesn't achieve anything
other than push the verification that the compiler does in a language
like C++ into the test suite, so if that is what you mean by black box
I see it as a bad thing.

Vidar
 
T

Tomasz Wegrzanowski

Because that's a method call, not a function-style call.

So what's the final rule ?

Is it something like:
protected method can be called if "implicit self" is used
or if self is the same or sub class of class in which method
was defined, and only from a method definition by `def'"

Is it correct ?
Why does it work this way (especially the `def only' part) ?
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Private visibility should be removed from Ruby 2 [was: Caveats with #method_missing]"

|> |* remove "protected" visibility completely
|
|Nobody uses "protected" (0 uses in standard library - can anybody find some
|code that actually uses it ?). Nobody understands it.

"protected" is like "friend" in C++. Currently a few programs use it,
but it does not mean it isn't useful.

|How was it supposed to work ? Am I the only one with a problem here ?

This is a bug. I should have checked protected visibility based on
real "self" within instance_eval. It will be fixed soon.

|And getting rid of it make metaprogramming easier.
|One example: I have no idea how to make delegation by method_missing
|that behaves correctly with public, protected and private methods.
|Delegation would either have to ignore visibility (what is wrong -
|see preexplanation again) or fail to forward some methods.

Removing visibility makes the issue much easier, I admit. But you may
agree that visibility has its own merit on the other hand. It's just
a trade off. It might mean the demand for the delegation along with
the original visibility.

I will be back with your other points later.

matz.
 

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,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top