Access control and class methods

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!

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

···

On 11/6/05, Mads Kristensen <madsk@foo.bar> wrote:

I was just wondering: does access control not apply to class methods?

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.

Trans wrote:

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 :wink:

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

Mads Kristensen wrote:

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:

(Seems like only yesterday :wink:

daz

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

···

On Nov 6, 2005, at 9:47 AM, Mads Kristensen wrote:

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

   #
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

daz wrote:

Check this "archive" thread from 5 Nov 2005:

qurl.net - This website is for sale! - qurl Resources and Information.

(Seems like only yesterday :wink:

I'm sorry. I should have done a simple search in this newsgroup :wink:

Thanks for your reply!

- Mads

gwtmp01@mac.com wrote:

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.

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

···

On Nov 6, 2005, at 9:47 AM, Mads Kristensen wrote:

gwtmp01@mac.com wrote:

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

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

···

On Nov 6, 2005, at 9:47 AM, Mads Kristensen wrote:

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

···

On Nov 6, 2005, at 9:45 PM, Eero Saynatkari wrote:

  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.

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

···

On Nov 6, 2005, at 11:07 PM, zdennis wrote:

Selon gwtmp01@mac.com:

>
> 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.

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 of
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 is
still *no* agreement on how to call them (AFAIK, matz himself still prefers 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 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.

···

--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.

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

···

On Nov 7, 2005, at 3:36 AM, Christophe Grandsire wrote:

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.

Selon gwtmp01@mac.com:

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, different
syntax. And I don't think the similarity of the two symbols is so close that
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 too
similar for the completely different meanings they have. 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?

···

--
Christophe Grandsire.

http://rainbow.conlang.free.fr

It takes a straight mind to create a twisted conlang.

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

···

On Nov 7, 2005, at 10:06 AM, Christophe Grandsire wrote:

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?