Archive for December, 2003

Private Methods in C++ and Ruby

I’ve recently had to re-learn the meanings of protected and private accessibility for Ruby methods, and how those meanings differ from the same keywords in C++, and so I thought I’d summarize what I’ve learned here. Note that to keep things as simple as possible, I’m ignoring the exceptions to these rules for C++ that friend classes introduce.

First, the good news. As far as I can determine, everything that you know about protected member functions in C++ classes applies to protected methods in Ruby classes. That is to say, a protected method can be called from other methods in the same class, as well as from methods in derived classes. Also, one instance of a class can call protected methods on other instances of the same class.

There are some subtle differences, however, when it comes to private member functions and methods. In C++, a private member function can only be called from member functions of the class in which it’s declared. So if you declare a private member function foo() in a base class:


    class Base {
    private:
        void foo();
    };

then other member functions in Base can call foo():

    class Base {
    private:
        void foo();
    public:
        void spam() {
            foo(); // this is allowed since spam() is declared in the same class as foo()
        }
    };
but foo() is not visible to classes derived from Base:

    class Derived : public Base {
    public:
        void bar() {
            foo(); // this should generate a compile-time error
        }
    };
This brings us to the first difference between private member functions in C++ and private methods in Ruby, and it has to do with the visibility of private methods in derived classes. As we’ve just seen, C++ private member functions are not visible in derived classes. In Ruby, however, private methods are visible in derived classes, i.e. if foo is declared private in the base class:

    class Base
    private
      def foo; end
    end
then methods in the derived class can call it:

    class Derived < Base
      def bar
        foo # this is allowed in Ruby
      end
    end
The next difference between private member functions in C++ and private methods in Ruby has to do with the objects on which the private member function (or method) can be called. In C++, you can call a private member function on any instance of the class that declares that member function, e.g.

    class Base {
    private:
        void foo();
    public:
        void spam(Base *otherObject) {
            foo();              // this is allowed
            otherObject->foo(); // and so is this
        }
    };
In Ruby, you can’t specify the receiver when calling a private method. Put another way, you can only call a private method on self, either implicitly or explicitly, e.g.

    class Base
    private
      def foo; end
    public
      def spam(otherObject)
        foo             # this is allowed in Ruby (self is implicit)
        self.foo        # so is this
        otherObject.foo # but this isn't
      end
    end
In C++, one would choose the private access over protected access for a member function to better enforce data hiding: the less that derived classes “know” about the base class implementation, the better. In Ruby, however, there doesn’t seem to be any direct way to hide base class methods from derived classes. One person summed up the distinctions by saying that in C++, “private” means “private to this class”, while in Ruby it means “private to this instance”.

Local & State News

The Associated Press reports that Auburn High School senior Cameron Coles scored a perfect 36 on the ACT. He was the only student in Alabama, and one of five nationwide, to do so during the September testing. AHS is my alma mater (class of 1988) and so this is especially nice to see.

Also from the AP, “American Idol” winner Ruben Studdard (from Birmingham, Alabama) is nominated for best male R&B vocal performance for his performance of “Superstar”, from his upcoming solo album “Soulful”. “Idol” runner-up Clay Aiken received no nominations for “Measure of a Man”, his major-label debut.

Start Here

At the beginning of the week, Why the Lucky Stiff launched What a Quiet Stiff, a new wholly owned subsidiary of his popular web site. His request for people to take advantage of the RSS feed reminded me that I never got around to finding out what RSS is all about, and so I started doing some research about what it is and what kinds of RSS parsing libraries are available for Ruby.

The first stop was Chad Fowler’s Ruby/RSS module, which is probably very good but presented two immediate problems. First, it relies on yet another extension (xmlparser) for its XML parsing instead of the now-standard REXML. Second, it only works for RSS version 0.91, and Why’s RSS feed is in version 2.0 format. The next and last stop (for now) was kou’s RSS parser, which does use REXML and supports RSS 2.0 as well.

After a flurry of hacking, I managed to put together a little FXRuby-based GUI application for viewing the latest images from WAQS. After a few more touches I will probably publish it to RubyForge; it is probably a little too big to include as an example amongst the shorter (and easier-to-digest) FXRuby example programs. Watch this space for the latest developments.