Archive for the 'ruby' Category

Ruby’s Operator Expressions and Message Expressions using Operator Methods Yield Different Results

Thursday, February 21st, 2008

In pure object-oriented languages, such as Smalltalk, numerical and boolean expressions are expressed as message expressions. Non-pure object-oriented languages typically provide operators like +, -, *, /, &&, || to write numerical and boolean expressions, and they have precedence rules for operators, so that a numerical expression has the same semantics as in mathematics.

Interestingly, Ruby includes operators and some of them are implemented as methods, so-called operator methods. Let’s try some examples.

irb(main):001:0> 3 + 4 * 6
=> 27

That is what we expect. It shows that Ruby implements operator precedence. * has precedence over +.

* and + are implemented as operator methods. The pickaxe book states that: “If the operator in an operator expression corresponds to a redefinable method, Ruby will execute the operator expression expr1 operator expr2 as if it had been written (expr1).operator(expr2).” This means that the previous example can also be written as:

irb(main):002:0> 3.+(4).*(6)
=> 42

The result is what we expect. Messages are sent from left to right in an expression like this. The precedence rules do not apply when using the message passing form.

But according to the book, the two forms should yield the same result. They don’t.

Classes can implement operator methods as well, as shown in this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Number
  def initialize(initialValue = 0)
    @value = initialValue
  end
  def  value
    @value
  end
  def +(other)
    self.class.new(self.value + other.value)
  end
  def *(other)
    self.class.new(self.value * other.value)
  end
end

Let’s try some expressions:

irb(main):003:0> (Number.new(3) + Number.new(4) * Number.new(6)).value
=> 27

This is consistent the precedence rules of the operators. When this expression is rewritten with messages, this is the result:

irb(main):004:0> Number.new(3).+(Number.new(4)).*(Number.new(6)).value
=> 42

Again, this shows that the precedence rules do not apply.

Although I expect that, consistent with other object-oriented languages, no precedence rules apply when messages are sent in sequence, Ruby states that using the operator form and the message passing form should be equivalent, but they clearly are not. That is very confusing and error-prone.

Installing Ruby In Your Home Folder On Dreamhost

Thursday, November 22nd, 2007

I wanted to install a more recent ruby on my dreamhost hosting, with more recent gems then provided standard, so I decided to install ruby in my home directory. Below the steps I took to get it working. It worked out of the box for me, so now, I have full control over which exact gems and versions I use, independent of what dreamhost provides.

First, download the ruby tar ball:
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p110.tar.gz
(note: be sure to check on the ruby site to get the latest stable sources, in the mean time, newer patchlevels might be available)

untar the tar ball:

tar -xvf ../ruby-1.8.6-p110.tar.gz

In your home folder, create a ruby directory to hold the installation:

mkdir ~/ruby

Change directory to the untarred directory. In that directory, run configure pointing to your local ruby directory:

./configure –prefix=/home/username/ruby

Then run:

make
make install

You now should have a ruby installation in /home/username/ruby.

In your home folder, edit your .bash_profile file and add the ruby bin folder to your path:

export PATH=”$HOME/ruby/bin:$PATH”

Source this file and run ruby -v

source ~/.bash_profile
ruby -v

SUCCESS:
ruby 1.8.6 (2007-09-23 patchlevel 110) [i686-linux]

Next, install ruby gem, the ruby package manager. Ruby gems can be found here

Get the latest version:

wget http://rubyforge.org/frs/download.php/28174/rubygems-0.9.5.tgz

untar:

tar -xvzf rubygems-0.9.5.tgz

cd rubygems-0.9.5

ruby setup.rb (note, be sure that you have your home backed ruby in your path!!)

Install rake:

gem install –remote rake

gem install fcgi

Do not forget to update the shebang in the dispatcher.fcgi file to the correct path

#!/home/username/ruby/bin/ruby

Then, install rails:

gem install rails

And you are rolling!!!

Note that in order to deploy in production mode, you need to uncomment the ENV[’RAILS_ENV’] ||= ‘production’ line in environment.rb.

Below the deployment recipe I used:


ssh_options[:paranoid] = false
set :user, 'user'
set :password, 'passwd'
set :application, "app"
set :repository, "http://url_to_svn_repository"
set :deploy_to, "/home/username/www.killerapp.com"

role :app, "www.killerapp.com"
role :web, "www.killerapp.com"
role :db, "www.killerdb.com", :primary => true

set :checkout, "export"

namespace :deploy do
desc "Restart the FCGI processes on the app server as a regular user."
task :restart, :roles => :app do
run "#{current_path}/script/process/reaper --dispatcher=dispatch.fcgi"
end

end

Thanks to Geoffrey Grosenbach for getting the inspiration for this recipe.

Hope this helps.

Ruby’s “private”: not as Private as You Expect

Tuesday, April 24th, 2007

I expect that, if a language borrows a concept from another language, and if that language even uses the same name for the concept, the concept also has the same semantics. That is not the case for “private” access control in Ruby.

In Java and C++, the sematics of the “private” access modifier for a method is: the method can only be called by methods of the class that declares the private method.

In Ruby, the semantics is (taken from the pickaxe book, page 35): private methods can be called only in the context of the current object. A bit further in the book: The difference between “protected” and “private” is fairly subtle and is different in Ruby than in most common OO languages.

Indeed, the difference is subtle, certainly for C++ and Java developers learning Ruby. As the sematics above already indicate, C++ and Java have a class focus, while Ruby has an instance focus. Private in C++ and Java means: private to the class. In Ruby, it means: private to the instance.

There is another aspect of the semantics that is important. In C++ and Java, a private method can be called on a different instance than the one executing the current method. In Ruby, private methods can only be invoked on the same instance, which is enforced syntactically: private methods can only be invoked without a receiver or with self.

Because in Ruby private methods are private to an instance, they can be invoked by methods in a subclass, illustrated by the following code snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Superclass
    private
        def m1()
            puts "Superclass.m1"
        end
end
 
class Subclass < Superclass
    public
        def m2()
            m1()
            puts "Subclass.m2"
        end
end
 
Subclass.new().m2()

The output of the program is:

irb(main):017:0> Subclass.new().m2()
Superclass.m1
Subclass.m2
=> nil

Private methods can also be overridden, as shown in this code snippet:

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Superclass
    private
        def m()
            puts "Superclass.m"
        end
end
 
class Subclass < Superclass
    public
        def m()
            super()
            puts "Subclass.m"
        end
end
 
Subclass.new.m()

The output of the program is:

irb(main):017:0> Subclass.new.m()
Superclass.m
Subclass.m
=> nil

A singleton method can even override a private method of the class of the instance, as illustrated by this code snippet:

33
34
35
36
37
38
39
40
41
42
43
44
45
class MyClass
    private
        def m()
            puts "MyClass.m"
        end
end
 
object = MyClass.new()
def object.m()
    super()
    puts "object.m"
end
object.m()

The output of the program is:

irb(main):013:0> object.m()
MyClass.m
object.m
=> nil

The conclusion is that Ruby has no way to make methods private in the C++ and Java sense. In my opinion, that is a good thing, because private methods are bad for reusability. But I do not believe that using the word “private” was a good choice.

Simplicity, Consistency, Expressiveness and Elegance of Ruby

Sunday, April 15th, 2007

I have grown up as a software developer with Smalltalk and other non-statically typed programming languages like Python and Scheme. I even took part in the development of a prototype-based language called Agora.

Now that Ruby is taking off, and after Nick showed me how to create a small Ruby on Rails application in no time, I am intrigued by the language. I am intrigued because the inventors of Ruby claim to have used some concepts from Smalltalk and I know the ins and outs of Smalltalk fairly well. I am also intrigued because the little time I spent coding the RoR application showed me two things: (1) creating a RoR application requires little real programming, and (2) from the first line of Ruby code I was struck by the ad hoc nature of some Ruby language constructs.

When I learn a new language, I look for qualities such as simplicity, consistency, expressiveness and elegance, qualities that influence my productivity when coding. This post is the first in a row of articles on Ruby to explore how well Ruby scores on these qualities.


Close
E-mail It
Socialized through Gregarious 42