StackOverflow cool Ruby questions 4

Welcome to the fourth post of this series. Just before proceeding to the questions, I would like to mention the great Metaprogramming Ruby: Program Like the Ruby Pros book by Paolo Perrotta, a very good book that explains the metaprogramming aspects of the Ruby language.
Now let's get going!

Scope gates

Taken from the above mentioned book:

There are exactly three places where a program leaves the previous scope behind and opens a new one:
• Class definitions • Module definitions • Methods
Scope changes whenever the program enters (or exits) a class or module definition or a method. These three borders are marked by the keywords class, module, and def, respectively. Each of these keywords acts like a Scope Gate.

The question title is: Closure doesn’t work

The question text is:
If block is a closure, why this code does not work? And how to make it work?

def R(arg)
  Class.new do
    def foo
      puts arg
    end
  end
end

class A < R("Hello!")
end

A.new.foo #throws undefined local variable or method `arg' for #<a:0x2840538>
</a:0x2840538>

The answer is:
Blocks are closures and arg is indeed available inside the Class.new block. It's just not available inside the foo method because def starts a new scope. If you replace def with define_method, which takes a block, you'll see the result you want:

def R(arg)
  Class.new do
    define_method(:foo) do
      puts arg
    end
  end
end

class A < R("Hello!")
end

A.new.foo # Prints: Hello!

Almost everything in Ruby is an object

The question title is: Examples of ‘Things’ that are not Objects in Ruby

The question text is:
"Everything is an object" was one of the first things I learned about Ruby, but in Peter Cooper's Beginning Ruby: From Novice to Professional book, it is mentioned that "almost everything in Ruby is an object".

Can you give me some examples of things that are not objects in Ruby?

The answer is:
he most obvious one that jumps into my head would be blocks. Blocks can be easily reified to a Proc object, either by using the &block parameter form in a parameter list or by using lambda, proc, Proc.new or (in Ruby 1.9) the "stabby lambda" syntax. But on its own, they aren't objects.

Another example are built in operators: while methods are objects, some operators are not implemented as methods (and, or &&, ||), so those operators aren't objects.

Hash keys

The idea here is that whenever you want to define your own keys types for Ruby hashes, then you need to define 2 methods #eq? and #hash for those types.

The question title is: How to make object instance a hash key in Ruby?

The question text is:
I have a class Foo with a few member variables. When all values in two instances of the class are equal I want the objects to be 'equal'. I'd then like these objects to be keys in my hash. When I currently try this, the hash treats each instance as unequal.

h = {}
f1 = Foo.new(a,b)
f2 = Foo.new(a,b)

f1 and f2 should be equal at this point.

h[f1] = 7
h[f2] = 8
puts h[f1]

should print 8

The answer is:
See http://ruby-doc.org/core/classes/Hash.html

Hash uses key.eql? to test keys for equality. If you need to use instances of your own classes as keys in a Hash, it is recommended that you define both the eql? and hash methods. The hash method must have the property that a.eql?(b) implies a.hash == b.hash.

The eql? method is easy to implement: return true if all member variables are the same. For the hash method, use [@data1, @data2].hash

Kernel#abort

The question title is: Ruby - Exit Message

The question text is:
Is there a one line function call that quits the program and displays a message? I know in Perl its as simple as this:

die("Message goes here")

Essentially I'm just tired of typing this:

puts "Message goes here"
exit

The answer is:
The 'abort' function does this. For example:

abort("Message goes here")