March 08, 2005

const_missing

There's an ongoing weekly quiz in the Ruby mailing list. This week's theme is roman numerals -- writing a program that can read roman numerals from the standard input and print out their arabic representation. A few solutions have been posted, standard stuff. But Dave Burt complemented his with a very neat hack. He makes it possible to treat integers and roman numerals interchangeably, and to perform arithmetic operations with them:

VII + 3 -> X
XIV / 2 -> VII
VIII.divmod(III) -> [II, II]
etc.

Part of this is achieved by redefining the const_missing method of the Object class, which kicks in whenever the interpreter finds reference to an unknown constant.

def Object.const_missing sym
    # verify that the constant is a roman numeral
    raise NameError.new("uninitialized constant: #{sym}") unless RomanNumerals::REGEXP === sym.to_s
    # define the constant and return it
    const_set(sym, RomanNumeral.get(sym))
end


The arithmetic operations are made possible by redefining RomanNumeral's method_missing method with code that delegates unknown operations to the it's integer representation.

Take a peek at the complete solution.

Labels:

0 Comments:

Post a Comment

<< Home