Ruby Access Control – Are Private And Protected Methods Only A Guideline?

ProtectA few days ago Chad Fowler ran the following quick quiz on Twitter:

Ruby quiz: in 140 chrs or less, why doesn't this work: class Y; def a;
self.x end; private; def x; puts "hi" end end; Y.new.a

Here is the formatted version:

class Y
  def a
    self.x
  end
  private
  def x
    puts "hi"
  end
end
 
Y.new.a

Running this produces the following error:

a.rb:3:in `a': private method `x' called for #<Y:0x7f819a82d548> (NoMethodError)
    from a.rb:11

I wasn't immediately able to figure out what was wrong with this code and since access control is one of those fundamental things that you should know, if you want to be a decent Ruby developer, I decided to dig a little further to figure it out. Here is the scoop.

Private, Protected and Public – Ruby Method Visibility

The concept of private, protected and public methods in Ruby is somewhat different than it is in languages like Java (well, not so much public, that's very similar :)). In Java if a method is declared private, it can only be accessed from other methods in the same class. When a method is declared protected it can be accessed by other classes in the same package as well as by subclasses of its class in a different package. When a method is public it is – of course – always visible to everyone. So, in essence with Java, these keywords protect the various members from access by classes, depending on where these classes are in the inheritance/package hierarchy.

Faster List Intersection Using Skip Pointers

IntersectionAs I mentioned in my previous post about array intersection, all the work we did was to enable us to experiment with skip pointers. You may remember me saying that list intersection was the most important operation when it comes to search engines. This is because in web search, most queries are implicitly intersections. Consider, when your query contains multiple words (e.g. "car repairs", "britney spears songs" etc.) the search engine will translate this into – ("car AND repairs", "britney AND spears AND songs"), which means it will be intersecting 2 or more postings lists in order to return a result. Because intersection is so crucial, search engines try to speed it up in any way possible. One such way is to use skip pointers.

What Are Skip Pointers

As you recall from my previous post if the sizes of our two posting lists are x and y, the intersection takes x+y operations. Skip pointers allow us to potentially complete the intersection in less than x+y operations. Here is how. At indexing time, we augment our posting lists of document identifiers with a set of "short cut" pointers that reference values further along in the list e.g.:

Skip Pointers

An Interview Question That Prints Out Its Own Source Code (In Ruby)

A program that prints out its own source code (without reading in and outputting it's source file) is known as a quine. I've known about these things for years, but never really bothered trying to work it out. It requires thinking in a circular fashion which makes your head hurt :). However, a little while ago a realized that this would actually make a great programming interview question, so I thought I had better give this a crack, using Ruby – of course.

Why It's A Great Interview Question

Before we get to the Ruby quine hackery that I came up with, here is why I think it is a great question. You see, the good thing about this question is the fact that it is relatively small (doesn't take too much time) but at the same time it is not binary (i.e. not yes/no or knows/doesn't know or can do/can't do). Here is how I see it potentially panning out and what it means.

You ask the question, and they draw up an answer for you almost instantly without batting an eyelid.

  • Clearly they have heard of this before, which shows they have an interest and some involvement in the wider programming community.

Timing Ruby Code – It Is Easy With Benchmark

Recently I needed to time some Ruby code as it was running (related to my post on list intersection and another post on skip pointers which I haven't finished writing yet). Being a bit too keen (as I often am :)) and seeing as it would be fairly easy to do, I decided to quickly roll an implementation similar to the following.

beginning_time = Time.now
(1..10000).each { |i| i }
end_time = Time.now
puts "Time elapsed #{(end_time - beginning_time)*1000} milliseconds"

You get the current time before and the current time after the code you need to measure the running time of and you simply subtract them from each other (to get the time in seconds). The output is as follows:

alan@alan-ubuntu-vm:~/projects$ ruby time.rb
Time elapsed 4.049 milliseconds

But this seemed rather inflexible, and you wouldn't want to have to do it over and over again, so I rolled it into a method, to allow myself to time the execution of other methods, like so.

def time_method(method, *args)
  beginning_time = Time.now
  self.send(method, args)
  end_time = Time.now
  puts "Time elapsed #{(end_time - beginning_time)*1000} milliseconds"
end
 
def method_to_time(*args)
  (1..10000).each { |i| i }
end
 
time_method(:method_to_time)

As you can see we can now pass a symbol version of the method name we want to time into our time_method. Inside the time_method we will call "send" on the current object passing in the method name (which will essentially call the method we want to time) and will wrap this call in our timing code, producing similar output (to that from above):

Writing A More Ruby-ish Array Intersection Function And Sorting Structs

In my previous post on boolean search, we wrote an efficient list (array) intersection function. But, to be honest, I wasn’t very happy with it. Considering the fact that we were using Ruby, it just wasn’t very Ruby-like. So, this time I am going to try and show how that function can be re-written to not only be more Ruby-ish but to also be tighter and easier to understand. In addition I will look at a couple of interesting aspects of OpenStruct, which will lead nicely into my next post on skip pointers (I’ve spoken about covering skip pointers before).

The Ruby-ish Intersection Function

The last time we implemented an array intersection function it looked like this:

def intersect_lists(list1, list2)
  final_list = []
  current_list1_index = 0
  current_list2_index = 0
 
  while(current_list1_index < list1.length && 
                          current_list2_index < list2.length)
    if list1[current_list1_index] == list2[current_list2_index]
      final_list << list1[current_list1_index]
      current_list1_index += 1
      current_list2_index += 1
    elsif list1[current_list1_index] < list2[current_list2_index]
      current_list1_index += 1
    else
      current_list2_index += 1
    end
  end
  final_list
end

There is actually nothing wrong with the code itself. It is an efficient implementation. The reason it is efficient is due to the fact that we only need to walk through each of the lists once, in order to produce the intersected list. So if the sizes of our two lists are x and y, the intersection takes x+y operations, i.e. the complexity of the algorithm is O(x+y). If we were writing that function in C, everything would be fine at this point, but we’re using Ruby. What we really want our function to look like is something along the lines of:

Fetching RSS Feeds With Ruby From Behind A Proxy

I was trying to fetch some RSS feeds with Ruby the other day. I just needed something quick (but not dirty, I don’t like dirty) to validate a couple of things I was trying out with Rails. It is not that difficult to fetch feeds, there is enough info around, but unfortunately I was behind a proxy at the time and this is where things went south quickly. It just seems that the Ruby ecosystem has this natural hatred for corporate proxies, it’s come to bite me time and time again. This is something that really needs to be rectified if we want Ruby to penetrate further into the corporate world, but that’s a story for another post.

Fetching Feeds Using Feedzirra

The first thing I tried to do was use Feedzirra, which I found out about from Railscasts. At first sight everything seemed ok, it will respect the proxy settings you have configured in your environment (i.e. the http_proxy environment variable) as it uses a fork of Curb (libcurl bindings for Ruby). However if you haven’t configured the proxy within your environment, everything falls over since there doesn’t seem to be a way to supply your proxy settings to Feedzirra directly. I would be happy to be corrected here! I wanted to fetch feeds from within a Rails app, and Rails doesn’t inherit your environment variables – no good (I am sure there are ways to make Rails do so, but like I said – don’t want dirty).

Using Multiple Rubies Seamlessly On The One Machine With Rvm

If you’re into Ruby and are not yet using RVM (ruby version manager) you’re doing yourself a disservice. It’s a great little tool that allows you to easily have multiple Ruby installs on the one machine and will manage all the associated complexity for you (@markmansour originally put me onto it). You can switch between different Ruby versions instantly and if you need to make sure that your code works with multiple Ruby versions (e.g. 1.8 and 1.9, or 1.8 and JRuby), then you will really, really love it. Well, I hope you’re excited, so lets get you set up with your very own RVM install, you do need Linux (I am using Ubuntu), so if you need to work with multiple Rubies on windows, may god have mercy on your soul.

Installing RVM And Multiple Rubies

Ok, first thing first, RVM is a ruby gem so you will need to have some sort of Ruby install on your system already. It is a bit of a pain, but a small price to pay for the blessing you’re about to receive. Setting up rvm is pretty simple.

Firstly, install the gem:

Ruby Exceptions And Exception Handling

ExceptionRuby exceptions and error handling is not the most remarkable feature of the Ruby language. Infact, the way Ruby deals with exceptions is strikingly similar to other languages (such as Java etc.). But, I think all the stuff I’ve been writing about Ruby lately has taken on a life of it’s own for me :), so I am going to quickly go over this topic if only for completeness sakes.

Raising Exceptions

Getting Ruby to raise an exception is easy :). Ruby, like many other languages has a hierarchy of exception classes (that all inherit from the class Exception), some of these are familiar and fairly easy to produce, for example ZeroDivisionError or NoMethodError. Here is some code which will do just that:

1/0

or

blah = Object.new
blah.hello

Of course you don’t have to wait for Ruby to raise exceptions for you, you can do so explicitly in your code with the raise keyword (it is actually a method). Lets write a method where we explicitly raise an exception if the argument we pass in is false:

def i_must_have_truth(value)
  raise TypeError, 'You must give me truth' if value == false
end
 
i_must_have_truth false

this prints:

Ruby Equality And Object Comparison

ComparisonJust like other object oriented languages, Ruby gives an object ways to find out if it is equal to, greater or less than another object. Object comparison is extremely important, not only do we tend to often explicitly compare objects to each other e.g.:

string1 = "abc"
if "abc" == string1
  puts 'they are equal'
end

but objects are frequently compared and tested for equality ‘behind the scenes’, by core and library classes (i.e. ordering of objects in collections etc.). So, lets not waste any time and jump straight in.

Testing Objects For Equality

Ruby has three main equality test methods, ==, eql? and equal?. These methods normally live in the Object class and since all other Ruby classes inherit from Object, they automatically gain access to these three methods. Inside the Object class all there methods do exactly the same thing, they test if two objects are exactly the same object. That is to say, both objects must have the same object id. We can easily demonstrate this e.g.:

string1 = "abc"
class MyObject
end
object1 = MyObject.new
object2 = object1
object3 = MyObject.new
 
puts "Object 1 is == to object 2: #{object1 == object2}"
puts "Object 1 is eql? to object 2: #{object1.eql? object2}"
puts "Object 1 is equal? to object 2: #{object1.equal? object2}"
puts "Object 1 is == to object 3: #{object1 == object3}"
puts "Object 1 is eql? to object 3: #{object1.eql? object3}"
puts "Object 1 is equal? to object 3: #{object1.equal? object3}"

The output is:

True, False And Nil Objects In Ruby

TrueEvery expression and every object in Ruby has a boolean value, which means that every object and every expression must either evaluate to true or to false. This makes true and false rather special values. But, they are not just empty value or simple keywords, just like with everything else, both true and false are Ruby objects.

The True And False Objects

You’re probably aware that true and false are reserved words in Ruby which means you can’t use them as a variable or method name. But both true and false are also fully fledged objects. Ruby has two special classes called:

TrueClass

and

FalseClass

and the objects true and false are the only instances of these classes. Infact Ruby won’t let you create any more instances of these classes, you can go ahead and try e.g.:

irb(main):001:0> true.class
=> TrueClass
irb(main):002:0> false.class
=> FalseClass
irb(main):003:0> p = TrueClass.new
NoMethodError: undefined method `new' for TrueClass:Class
        from (irb):3
irb(main):004:0> q = FalseClass.new
NoMethodError: undefined method `new' for FalseClass:Class
        from (irb):4
irb(main):005:0>

But what about every Ruby expression evaluating to either true or false? Well, every Ruby expression evaluates to an object and every Ruby object in turn can be used in a conditional statement which means every object ultimately must evaluate to a boolean value. You can test this out on your own: