2015年8月27日木曜日

[Ruby]Fizz Buzz

Fizz Buzzを小難しく書いてみました。
ルールが変わったら、@rule_pairsの初期値を変えればよいはず。
[[:fizz, 3], [:buzz, 5] , [:torifuku, 10] ]とか。

module FizBuzz
  class << self
    private
    def rule_pairs
      @rule_pairs ||= [[:fizz, 3], [:buzz, 5]].map(&:freeze).freeze
    end
  end

  method_names = rule_pairs.map(&:first).map(&:freeze).freeze
  define_method(:say) do
    value = method_names.map{|name| lambda{__send__ name}}.inject('') do |result, proc|
      result + proc.()
    end
    value.empty? ? self : value
  end

  private
  rule_pairs.each do |sym, n|
    define_method("#{sym}?") do
      self % n == 0
    end

    define_method(sym) do
      __send__("#{sym}?") ? sym.to_s.capitalize : ''
    end
  end
end

class Integer
  include FizBuzz
end

p (1..100).map(&:say)
p FizBuzz.private_methods.grep /rule_pairs/ # => [:rule_pairs]
p FizBuzz.public_instance_methods.grep /say/ # => [:say]
p FizBuzz.private_instance_methods.grep /[fi|bu]zz/ # => [:fizz?, :fizz, :buzz?, :buzz]

以下のようなメソッドを定義しています。
p FizBuzz.private_methods.grep /rule_pairs/ # => [:rule_pairs]
p FizBuzz.public_instance_methods.grep /say/ # => [:say]
p FizBuzz.private_instance_methods.grep /[fi|bu]zz/ # => [:fizz?, :fizz, :buzz?, :buzz]

0 件のコメント:

コメントを投稿