急にFizzBuzz

モジュールによるMonkey Patch。

module FizzBuzz
  Divisor = [ 3,      5      ]
  Strings = [ 'Fizz', 'Buzz' ]
  
  def fizzbuzz
    (rests = Divisor.map{|d| self % d == 0}).inject{|r, i| r || i } ?
      rests.zip(Strings).map{|r, s| r && s }.select{|x| x }.join : self
  end
end

class Integer
  include FizzBuzz
end

puts 1.upto(100).map(&:fizzbuzz)

# => 1
#    2
#    Fizz
#    4
#    Buzz
#    Fizz
#    7
#    (略)
#    98
#    Fizz
#    Buzz

で、無駄に凝ってみる。

module FizzBuzz
  def self.define(name, table = {})
    divisor = table.keys.sort
    strings = divisor.map{|k| table[k] }
    Module.new{
      define_method(name){
        (rests = divisor.map{|d| self % d == 0}).inject{|r, i| r || i } ?
          rests.zip(strings).map{|r, s| r && s }.select{|x| x }.join : self
      }
    }
  end
end

class Integer
  include FizzBuzz.define(:fizzbuzz,  3 => 'Fizz', 5 => 'Buzz')
  include FizzBuzz.define(:foobarbaz, 2 => 'Foo',  3 => 'Bar', 5 => 'Baz')
end

1.upto(100).tap{|iter| puts iter.map(&:fizzbuzz), '-' * 30, iter.map(&:foobarbaz) }

# => 1
#    2
#    Fizz
#    4
#    Buzz
#    Fizz
#    7
#    (略)
#    98
#    Fizz
#    Buzz
#    ----------
#    1
#    Foo
#    Bar
#    Foo
#    Baz
#    FooBar
#    7
#    Foo
#    Bar
#    FooBaz
#    11
#    (略)
#    Foo
#    89
#    FooBarBaz
#    91
#    Foo
#    Bar
#    Foo
#    Baz
#    FooBar
#    97
#    Foo
#    Bar
#    FooBaz