Women in Technology

Hear us Roar



Article:
  Ruby/Tk Primer: Creating a cron GUI Interface with Ruby/Tk
Subject:   Answer to the self.puts dilema
Date:   2004-06-28 18:40:32
From:   christopher_roach

I seem to be having a problem figuring out the posting mechanism here. I posted a reply to the earlier message, but so far I can only view it by clicking on the View link. So rather than trying another reply, I thought I would try making a normal post and hope for the best.

As for the problem your with the call to self.puts, aturley, you are correct. The puts method is a private method of the kernel module included in the main object, and thus, its methods are mixed-in (Ruby's way of implementing multiple inheritance) to the main object. The problem arises in how Ruby handles private methods. In Ruby, private methods cannot be called with an explicit receiver (this includes the self reference). So when you try to prepend the reference to self to the puts call you get a private method error.

I included the following sample class to prove my point.



class MyClass
def sayHello()
self.hello()
end


private
def hello()
puts "Hello, World!!!"
end
end


myClass = MyClass.new()
myClass.sayHello()


Try running it at the command line. You should get an error similar to the error you received when calling self.puts. If you remove private access modifier before the hello declaration, the program should execute properly.

I hope this staightens things out for you. One of the problems I have had with Ruby is fully understanding its access levels.

Thanks for the post.


Full Threads Newest First

Showing messages 1 through 5 of 5.

  • Answer to the self.puts dilema
    2004-07-19 16:12:40  Merc [View]

    Just a style note. Unlike Python, Ruby doesn't require parentheses around method calls that take no arguments (in fact, under most circumstances, it doesn't require them around methods that take arguments). That's why you can say puts "Hello World!", rather than puts("Hello World!").

    Most Ruby programmers omit them when they're not necessary, so they would write that code:


    class MyClass
    def sayHello()
    self.hello()
    end

    private
    def hello
    puts "Hello, World!!!"
    end
    end

    myClass = MyClass.new
    myClass.sayHello


    Part of the reason this is significant is that it allows you to treat functions as if they were attributes:


    class ComplexNumber
    attr_accessor :real, :complex
    end

    n = ComplexNumber.new
    n.real = 5
    n.complex = 6

    puts "(#{n.real}, #{n.complex})"


    n.real, and n.real= are actually method calls, but by omitting parentheses they look more natural.
    • Answer to the self.puts dilema
      2004-07-19 16:18:43  Merc [View]

      Oops, forgot to remove the parentheses around sayHello() and hello()
    • Answer to the self.puts dilema
      2004-07-19 20:30:53  Christopher Roach | O'Reilly Blogger [View]

      You're absolutely correct — you do not need the parentheses in a Ruby method call. My use of the parentheses in the example was simply because I am so used to using them in C/C++ and Java in my daily work.

      I did try to mention that Ruby does not need the parentheses (towards the middle of the third section), but I didn't really discuss any of the advantages of this property of the language. Therefore, I am glad that you pointed out that one of the advantages of not requiring the parentheses is Ruby's ability to treat a method like an attribute. Thus, setter and getter methods look just like direct attribute manipulation, giving the user the illusion that they are accessing data members directly while still following the OO concepts of data abstraction and encapsulation.

      Thanks for the example.
  • Answer to the self.puts dilema
    2004-07-19 18:23:49  wkaha@yahoo.com [View]

    IMHO There is no need to use self.hello.
    I've tried without and it works.
    • Answer to the self.puts dilema
      2004-07-19 20:06:35  Christopher Roach | O'Reilly Blogger [View]

      There really isn't any reason for the self.hello call other than to prove the point that a private method (hello, in this case) cannot be prefaced with a reference of any kind, even a reference to the object in which the private method resides. So, yes, you could try out the code without the self.hello call, but that would defeat the purpose of the example.

      The example is absolutely useless, I know, but it was created purely for pedagogical reasons rather than utility.