Delegating instance methods to the class method

class-method, instance-method, ruby

Solution

You could define a passthrough facility:

module Passthrough
  def passthrough(*methods)
    methods.each do |method|
      ## make sure the argument is the right type.
      raise ArgumentError if ! method.is_a?(Symbol)
      method_str = method.to_s
      self.class_eval("def #{method_str}(*args) ; self.class.#{method_str}(*args) ; end")
    end
  end
end

class Foo
  extend Passthrough

  def self::colour ; "green" ; end
  def self::is_spherical? ; true ; end
  passthrough :colour, :is_spherical?
end

f = Foo.new
puts(f.colour)
puts(Foo.colour)

I don't generally like using `eval`, but it should be pretty safe, here.

Problem

In Ruby, suppose I have a class `Foo` to allow me to catalogue my large collection of Foos. It's a fundamental law of nature that all Foos are green and spherical, so I have defined class methods as follows: ``` class Foo def self.colour "green" end def self.is_spherical? true end end ``` This lets me do ``` Foo.colour # "green" ``` but not ``` my_foo = Foo.new my_foo.colour # Error! ``` despite the fact that `my_foo` is plainly green. Obviously, I could define an instance method `colour` which calls `self.class.colour`, but that gets unwieldy if I have many such fundamental characteristics. I can also presumably do it by defining `method_missing` to try the class for any missing methods, but I'm unclear whether this is something I should be doing or an ugly hack, or how to do it safely (especially as I'm actually under ActiveRecord in Rails, which I understand does some Clever Fun Stuff with method_missing). What would you recommend?

Original source