Access control and class methods

  • Thread starter Mads Kristensen
  • Start date
M

Mads Kristensen

Hi.

I was just wondering: does access control not apply to class methods?
When I use the public, private and protected keywords on my instance
methods everything works fine, but when I try to do the same on class
methods they all end up being public anyway.

A small example:

--- Snip ---
#!/usr/bin/ruby

class Foo
public
def Foo._public (x)
puts "Hello in a public way #{x}"
end
protected
def Foo._protected (x)
puts "Hello in a protected way #{x}"
end
private
def Foo._private (x)
puts "Hello in a private way #{x}"
end
end

Foo::_public(1)
Foo::_protected(2)
Foo::_private(3)
--- Snip ---

Running this small program will call all three methods successfully
meaning that the private and protected class methods are called from a
place where _only_ public methods should be available.

So, are there no access control mechanisms for class methods? Or am i
missing domething here?

Best regards,
Mads D. Kristensen

BTW: Thanks to the creators of Ruby for a great little language. Good
work you guys!
 
T

Trans

It just doesn't work when done in this way becuase public, private and
protected are only effecting the incance level, so you need to get to
the class's "instance level", i.e. the class level.

class Foo
class << self
public
def _public (x)
puts "Hello in a public way #{x}"
end
protected
def _protected (x)
puts "Hello in a protected way #{x}"
end
private
def _private (x)
puts "Hello in a private way #{x}"
end
end
end

T.
 
S

Sean O'Halpin

I was just wondering: does access control not apply to class methods?
They do but you have to be in the right scope.

class Bar
class<<self
public
def _public (x)
puts "Hello in a public way #{x}"
end
protected
def _protected (x)
puts "Hello in a protected way #{x}"
end
private
def _private (x)
puts "Hello in a private way #{x}"
end
end
end

Bar::_public(1)
Bar::_protected(2)
Bar::_private(3)
__END__
Hello in a public way 1
C:/rubylib/experiments/ruby-talk/access-control-on-class-methods.rb:40:
protected method `_protected' called for Bar:Class (NoMethodError)

Regards

Sean
 
M

Mads Kristensen

Trans said:
It just doesn't work when done in this way becuase public, private and
protected are only effecting the incance level, so you need to get to
the class's "instance level", i.e. the class level.

OK. Thanks a lot for the swift reply.

But... it seems a bit messy though doesn't it? I mean, if defining a
class method should be done with the "inner class" syntax you have just
described to make the access control work, why is it at all possible to
define a class method using the "ClassName.methodName" syntax?

Ambiguities like that are no good in programming languages ;-)

And BTW: what does class<<self actually mean? One < would be inheritance
but what does it mean when there are two?

Best regards,
Mads Kristensen
 
D

daz

Mads said:
And BTW: what does class<<self actually mean? One < would be
inheritance but what does it mean when there are two?


*Nothing* to do with inheritance.

Check this "archive" thread from 5 Nov 2005:

http://qurl.net/mO

(Seems like only yesterday ;)


daz
 
G

gwtmp01

And BTW: what does class<<self actually mean? One < would be
inheritance but what does it mean when there are two?

One of the early hurdles I had with Ruby was trying to map
the "class <<object" syntax into a useful mental model. I'm
not sure why "<<" was selected. The semantics and syntax
don't seem to be related to those of the "<<" operator and
so you really need to form two separate mental models and just
know which one applies.

Why not something like:

class obj.eclass
#
end

Where Object#eclass is defined to return the eigenclass of
the receiver? Even a different keyword would be clearer:

eclass obj
#
end

It isn't a big deal but it does confuse newbies.


Gary Wright
 
E

Eero Saynatkari

One of the early hurdles I had with Ruby was trying to map
the "class <<object" syntax into a useful mental model. I'm
not sure why "<<" was selected. The semantics and syntax
don't seem to be related to those of the "<<" operator and
so you really need to form two separate mental models and just
know which one applies.

Well, it does bear some relation to inheritance which is why,
I would assume, the syntax was chosen. This...

class << foobar
# ...
end

...to me reads something like 'create an unnamed class which
inherits from foobar' and while not entirely accurate, illustrates
the basic idea of creating a special class/object based on some
existing object (foobar above) and defining behaviours on it.

In actuality, of course, the relationship is inverted as we are
not inheriting foobar but indeed making foobar inherit from a
new class but the end result behaves more or less the same.
Why not something like:

class obj.eclass
#
end

Where Object#eclass is defined to return the eigenclass of
the receiver? Even a different keyword would be clearer:

eclass obj
#
end

There was some debate about what the class should be called
(I still think #pouch). Also, the irreplaceable _why took it
upon himself to write a good description of Ruby's metaclasses.

http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html

There is also a small set of methods towards the bottom to help
dealing with metaclasses. Wrap it up in a file, put a notice
thanking _why for his contribution and use it with your code.
It isn't a big deal but it does confuse newbies.


Gary Wright

E
 
G

gwtmp01

class << foobar
# ...
end
[..]
In actuality, of course, the relationship is inverted as we are
not inheriting foobar but indeed making foobar inherit from a
new class but the end result behaves more or less the same.

This is all part of the confusion. An object is not a subclass
of its eigenclass so there is no class/subclass relationship
being asserted by the 'class <<object' syntax. The fact that
the symbol '<' is *also* used to assert a subclass relationship
in a similar notation (class A < B) hints at some sort of
subclassing assertion related to the object that doesn't exist.
The notation is a semantic head-fake.


Gary Wright
 
Z

zdennis

One of the early hurdles I had with Ruby was trying to map
the "class <<object" syntax into a useful mental model. I'm
not sure why "<<" was selected. The semantics and syntax
don't seem to be related to those of the "<<" operator and
so you really need to form two separate mental models and just
know which one applies.

Why not something like:

class obj.eclass
#
end

Once you know what << does, there is no confusion. I suspect the same would be with your proposed
code above. By looking at it, I am confused, but once I know what it means, there is no more confusion.

Zach
 
G

gwtmp01

Once you know what << does, there is no confusion.

Isn't that a truism?

As I said in my first post, I found the notation a
stumbling block for understanding the concept. Based
on the number of questions about the syntax that show
up on ruby-talk, I don't think my experience was particularly
unique.
I suspect the same would be with your proposed code above. By
looking at it, I am confused, but once I know what it means, there
is no more confusion.

There is a difference between a notation that is not suggestive
of anything in particular (an "empty vessel") and a notation that
is suggestive of something that is unrelated.

In any case, I was just throwing out some ideas for thought.
Here is another one:

Ruby currently allows for:

module M; end
class Y; end
class X < Y; end
class <<x; end

How about just using

object x; end

to open up the singleton class? This sort of goes with my previous
thought
that we can think of an object and its eigenclass as simply two views of
the same object.


Gary Wright
 
C

Christophe Grandsire

Selon (e-mail address removed):
Isn't that a truism?

As I said in my first post, I found the notation a
stumbling block for understanding the concept. Based
on the number of questions about the syntax that show
up on ruby-talk, I don't think my experience was particularly
unique.

Personally, I found the "class << object" *extremely* good at describing =
the
concept it referred to. As soon as I understood the *concept*, I found it=
made
sense, and helped me not to forget what the concept meant.
There is a difference between a notation that is not suggestive
of anything in particular (an "empty vessel") and a notation that
is suggestive of something that is unrelated.

I disagree that the notation is suggestive of something unrelated. YMMV.
In any case, I was just throwing out some ideas for thought.
Here is another one:

Ruby currently allows for:

module M; end
class Y; end
class X < Y; end
class <<x; end

How about just using

object x; end

to open up the singleton class? This sort of goes with my previous
thought
that we can think of an object and its eigenclass as simply two views o= f
the same object.

Using "object" to open up a *class* is about the most unintuitive thing I=
've
ever read. Using a new keyword like "eclass" unjustifiably favours one
denomination for those classes ("eigenclass") above others, while there i=
s
still *no* agreement on how to call them (AFAIK, matz himself still prefe=
rs to
call them singleton classes).

I still don't understand why the "class << object" notation is considered
unintuitive. I myself read it as "enter the singleton class of the partic=
ular
object". "<<" fits the "enter/come in" meaning quite well, and taken that=
way
it is pointing in the right direction: you're entering a class.
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.
 
G

gwtmp01

I still don't understand why the "class << object" notation is
considered
unintuitive. I myself read it as "enter the singleton class of the
particular
object". "<<" fits the "enter/come in" meaning quite well, and
taken that way
it is pointing in the right direction: you're entering a class.

And can understand this mental model of the syntax. It is what I've
come to
understand also. My point was that it is a *different* mental model
than
what I use for:

class A < B; end.

The A and B here have different relationship than the object/singleton
class relationship.


Gary Wright
 
C

Christophe Grandsire

Selon (e-mail address removed):
And can understand this mental model of the syntax. It is what I've
come to
understand also. My point was that it is a *different* mental model
than
what I use for:

class A < B; end.

The A and B here have different relationship than the object/singleton
class relationship.

True. That's why you don't use "<" but "<<". Different relationship, diff=
erent
syntax. And I don't think the similarity of the two symbols is so close t=
hat
it's problematic. I mean, one can write:
"string" < "other string" and
"string" << "other string"
and so far I've never seen someone complain that those two symbols are to=
o
similar for the completely different meanings they have. If one can accep=
t that
with strings '<' means comparison while '<<' means concatenation, why can=
not
they accept that after the keyword 'class' '<' means subclassing while '<=
<'
means getting the singleton class?
--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.
 
G

gwtmp01

If one can accept that with strings '<' means comparison while '<<'
means concatenation, why cannot
they accept that after the keyword 'class' '<' means subclassing
while '<<'
means getting the singleton class?

I can accept it. Semantic overloading happens all the time in
programming languages and natural languages. It also can be
confusing during the learning process or if the overloaded definitions
are only vaguely related. Of course once the overloaded meanings
have been internalized, it all seems much clearer than it did before.

Another Ruby example that bit me because of my C and C++ background:
Kernel#include.
It took me a long time to get my head around the fact that #include
is not some
sort of directive to read and interpret a file. Its behavior isn't
at all related
to the #include functionality of C and C++.


I was poking around to see if there was any historical debate on
overloading the left shift operator ('<<') for use with IO and then
by extension with other sorts of concatenation behavior. I found this
interesting example:


// Demonstrate shift operators
#include <iostream>
using namespace std;

int main() {
cout << "5 times 2 is " << (5 << 1) << endl
<< "20 divided by 4 is " << (20 >> 2) << endl;
}

The prose around this example neglected to explain that '<<' is used
in two vastly different ways. This would be pretty difficult
to digest if you didn't already understand how the semantics of '<<' had
been overloaded.


Gary Wright
 

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,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top