What?
In Ruby you have basically two ways of defining private methods:
# this is the first way to do it class Test def say_hello puts "I'm a private method" end private :say_hello end # and this is the second way class Test #other methods this class might have private def say_hello puts "I'm a private method" end end
I see a small problem with both approaches. In the first one, and the most obvious, is that you need to duplicate the method name as well as add an extra method call - private - just to change its visibility.
The second approach avoids this but adds the risk of accidentally putting a method that is intended to be public under the private section of the source file, which can render an annoying debugging session.
Why?
Personally, I like to have a smooth reading flow in my source files. That means that if the public method_a makes use of the private method_b, I want method_b defined right below its caller, which is possible - but verbose - using the private method call:
class Test def method_a method_b end def method_b puts "I'm a private method" end private :method_b end
But can be somewhat harder to accomplish if you decide to split your source file in sections:
class Test def method_a method_b end #just another public method. We might have several def method_c method_b end private def method_b puts "I'm a private method" end end
I wanted to be able to define a private method with a single reserved keyword…
How?
What if I could define a private method using this new syntax:
class Test def_p say_hello puts "I'm a private method" end end
It turns out I can.
Notice the def_p keyword? This is a new keyword I created by changing ruby’s parser and that behaves mostly like the def keyword, except that it defines a private method instead.
If you wanna read the code that allows this behavior and try it yourself, download the patch I wrote and apply it to the ruby source code - I patched version 1.9.1-p376.
After applying the patch, just build ruby as usual:
$ ./configure $ make
And then try running this script:
class Test def_p say_hello puts "I'm a private method" end end Test.new.say_hello
You should see the following output:
pvt.rb:10:in `': private method `say_hello' called for # (NoMethodError)
Happy hacking


you could achieve something similar using an ‘annotation’, without any need to hack the parser itself: http://bens.me.uk/2009/java-style-annotations-in-ruby
annotations, by the way, are how Python declares static (class) methods..
Interesting concept. I’ve read about it before - from a different source though.
I decided to hack into the parser because I believe this specific case should be somewhat part of the core language syntax - as it is in java, for instance.
Nevertheless, it was an interesting trip to hack through the parser and worth on its own!
Vlw!
Hmmmm, seems like you’ve been reading my mind. Just a few days ago I was thinking how crap it is to have to define method scopes the way they are now.
But the way I thought of to do it was just to create 3 methods
priv (private)
pub (public)
pro (protected)
that take blocks which would be the method definitions as they are now.
So that you could write something like
pub def my_method .. end
I haven’t tried to code this up yet but that is the way that I was thinking of doing it. And for me it is more natural to read it like that than def_p. But like they say, there are many ways to crack a nut, and many ways to skin a cat. So whatever works best for the individual I guess
You are right in that
reads better than
def_p my_method endI just chose def_p - as in define private - because I was more concerned about making it work.
Just a naming clarification here: priv | pro | pub cannot be methods in order to allow your syntax. They’d have to be reserved keywords - just like def - and have to be understood by the parser.
If you look at the patch I wrote, you’ll see it shouldn’t be too hard to implement it.
Cheers
Kudos for the good initiative
In the end I think “private def my_method” would be simpler and more natural to read, just like Groovy and Scala. Ruby should borrow from them.
tks!
Totally agree on the readability issue you pointed out. def_p is just a prototype to see how many people also miss this syntax.
It’s good to know I’m not alone.