StackOverflow cool Ruby questions 3

Welcome to the third post of this series. Just before diving into the new questions' set, I want to mention a little script that I wrote to notify the user when a new question is posted on Stackoverflow, it works on Mac and uses growl.
Now let's proceed to questions:

Relationship between the metaclass of base and derived classes

The question title is: What is the relationship between the metaclass of Base and Derived class in Ruby?

The question text is:

In Ruby, we could use super within singleton method to call the corresponding super class's singleton method, like the following code shows.

class Base
  def self.class_method
    puts "Base class method"
  end
end

class Derived < Base
  def self.class_method
    puts "Derived class method"
    super
  end
end

Derived.class_method
# Derived class method
# Base class method

However, I don't seem quite get how that call to super within Derived.class_method could reach Base.class_method. I'd assume that class_method is defined on their metaclass, does that mean their metaclass has parent/child relationship? (I can't quite confirm that by experiments)

I'm asking this question because I remembered seeing somewhere there's some kind of relationship between base and derived class' metaclass (but I can't find it any more). In addition to know how actually super works, I'd also like to confirm whether the two metaclasses are totally separate or not.

The answer is:
There are four class objects in play here:

<class>---class---><class>
Base               #Base
   ^                  ^
   |                  |
   |                  |
 super              super
   |                  |
   |                  |
<class>            <class>
Derived---class--->#Derived
</class></class></class></class>

Nomenclature:

  • <...> is the class of each object.
  • The name of the class is on the second line.
  • If the name starts with #, it's the eigenclass (aka singleton class).
  • super points to a class's superclass
  • class points to the class's class.

When you call Derived.class_method, Ruby follows the "right one and then up" rule: First go to the object's class, then follow the superclass chain up, stopping when the method is found:

  • The receiver of the "class_method" call is Derived. So follow the chain right to Derived's class object, which is its eigenclass (#Derived).
  • #Derived does not define the method, so Ruby follows the chain up the chain to #Derived's superclass, which is #Base.
  • The method is found there, so Ruby dispatches the message to #Base.class_method

You don't think I knew all this stuff off the top of my head, did you? Here's where my brain got all this meta juju: Metaprogramming Ruby.

Part 2. How to make an "eigenclass" (aka "singleton class") come out of hiding

class Object
  def eigenclass
    class << self
      self
    end
  end
end

This method will return the eigenclass of any object. Now, what about classes? Those are objects, too.

p Derived.eigenclass               # => #<class:derived>
p Derived.eigenclass.superclass    # => #<class:base>
p Base.eigenclass                  # => #<class:base>
</class:base></class:base></class:derived>

Note: Above is from Ruby1.9. When run under Ruby 1.8, you get a surprise:

p Derived.eigenclass.superclass    # => #<class:class>
</class:class>

Idiomatic object creation

The question title is: Idiomatic object creation in ruby

The question text is:

In ruby, I often find myself writing the following:

class Foo
  def initialize(bar, baz)
    @bar = bar
    @baz = baz
  end

  << more stuff >>

end

or even

class Foo
  attr_accessor :bar, :baz

  def initialize(bar, baz)
    @bar = bar
    @baz = baz
  end

  << more stuff >>

end

I'm always keen to minimize boilerplate as much as possible - so is there a more idiomatic way of creating objects in ruby?

The answer is:

Struct objects are classes which do almost what you want. The only difference is, the initialize method has nil as default value for all it's arguments. You use it like this

A= Struct.new(:a, :b, :c)

or

class A < Struc.new(:a, :b, :c)
end

Struct has one big drawback. You can not inherit from another class.

Block vs brackets

The question title is: Using do block vs brackets {}

The question text is:

New to ruby, put on your newbie gloves.

Is there any difference (obscure or practical) between the following two snippets?

my_array = [:uno, :dos, :tres]
my_array.each { |item| 
    puts item
}

my_array = [:uno, :dos, :tres]
my_array.each do |item| 
    puts item
end

I realize the bracket syntax would allow you to place the block on one line

my_array.each { |item| puts item }

but outside of that are there any compelling reasons to use one syntax over the other?

The answer is:

Ruby cookbook says bracket syntax has higher precedence order than do..end
Keep in mind that the bracket syntax has a higher precedence than the do..end syntax. Consider the following two snippets of code:

1.upto 3 do |x|
  puts x
end

1.upto 3 { |x| puts x }
# SyntaxError: compile error

Second example only works when parentheses is used, 1.upto(3) { |x| puts x }

String and whitespace

The question title is: See if a ruby string has whitespace in it

The question text is:

I want to see if a string has any white space in it. What's the most effective way of doing this in ruby?

Thanks

The answer is:

If by "white space" you mean in the Regular Expression sense, which is any of space character, tab, newline, carriage return or (I think) form-feed, then any of the answers provided will work:

s.match(/\s/)
s.index(/\s/)
s =~ /\s/
s[/\s/]

Index of the largest value in an array

The question title is: In Ruby, what is the cleanest way of obtaining the index of the largest value in an array?

The question text is:

If a is the array, I want a.index(a.max), but something more Ruby-like. It should be obvious, but I'm having trouble finding the answer at so and elsewhere. Obviously, I am new to Ruby.

The answer is:

For Ruby 1.8.7 or above:

a.each_with_index.max[1]

It does one iteration. Not entirely the most semantic thing ever, but if you find yourself doing this a lot, I would wrap it in an index_of_max method anyway.

each_with_index without a block returns an enumerator that gives the item and its index. We then send max to this enumerator, which does the standard max algorithm on item-index pairs. Array.<=> is implemented so that the first item determines the ordering (unless there's a tie, in which case the second is compared, and so on), so this works basically the same as doing max on an array of the values themselves. Then to get the index, we ask for the second item of the result (since we got a series of [value, index] pairs from each_with_index)