Ruby1.9の勉強に使った FizzBuzz サンプル

### Golf
```ruby:fizzbuzz_golf.rb
1.upto(100){|i|puts"#{[:Fizz][i%3]}#{[:Buzz][i%5]}"[/.+/]||i}
```
### ->、to_proc
```ruby:fizzbuzz_proc.rb
def fizzbuzz
  -> n { n % 15 == 0 ? :FizzBuzz : n % 5 == 0 ? :Buzz : n % 3 == 0 ? :Fizz : n }
end
puts (1..100).map(&fizzbuzz)
```
### オープンクラス、エイリアス、===
```ruby:fizzbuzz_open.rb
class Fixnum
  IS_FIZZBUZZ = -> m, n { n % m == 0 }.curry
  alias _to_s to_s
  def to_s
    case self
    when IS_FIZZBUZZ[15]
      "FizzBuzz"
    when IS_FIZZBUZZ[5]
      "Buzz"
    when IS_FIZZBUZZ[3]
      "Fizz"
    else
      _to_s
    end
  end
end
puts [*1..100]  
```
### 例外、===
```ruby:fizzbuzz_rescue.rb
def fizzbuzz(limit)
  e ||= 0
  ( e += 1 ) > limit ? return : raise
rescue lambda { |_| e % 15 == 0 }
  puts "FizzBuzz" ; retry
rescue lambda { |_| e % 5  == 0 }
  puts "Buzz"     ; retry
rescue lambda { |_| e % 3  == 0 }
  puts "Fizz"     ; retry
rescue lambda { |_| e }
  puts e          ; retry
end
fizzbuzz(100)
```
### Enumerator、メソッドチェイン
```ruby:fizzbuzz_chain.rb
puts 1.upto(100).with_object(nil)
                .map { |n, o| ( o ||= [] ) << :Fizz if n % 3 == 0; [n, o] }
                .map { |n, o| ( o ||= [] ) << :Buzz if n % 5 == 0; [n, o] }
                .map { |n, o| ( o || [n] ) * "" }
```
### Converter、Filter、to_proc
```ruby:fizzbuzz_converter.rb
class Converter
  
  def initialize
    @specs = []
  end
  
  def specs( value , &cond )
    @specs << lambda { |e| cond[e] ? value : nil }
  end
  
  def to_proc
    lambda { |e| 
      conved = @specs.map{ |spec| spec[e] }.join
      conved.empty? ? e : conved
    }
  end

end

if __FILE__ == $0

  arg   = ARGV[0] || 100
  limit = arg.to_i
  
  fizzbuzz  = Converter.new

  fizzbuzz.specs( "Fizz" ) { |n| n % 3 == 0 }
  fizzbuzz.specs( "Buzz" ) { |n| n % 5 == 0 }

  puts 1.upto(limit).map(&fizzbuzz)

end
```
### クラス化
```ruby:fizzbuzz_class.rb
class FizzBuzz
  
  def initialize( from = 1, to = 30 )
    @from, @to = [ from, to ].minmax
    block_given? ? yield( self ) : self
  end
  
  def spec( out, &cond )
    ( @specs ||= [] ) << lambda { |e| cond[ e ] ? out : nil }
  end
    
  def edit( &editor )
    @editor  = editor
  end
  
  def editor
    @editor || lambda { |e| e }
  end

  def format( &formatter )
    @formatter = formatter
  end
  
  def output( &formatter )
    @formatter = formatter if formatter
    result = @from.upto( @to ).map( &self )
    @formatter ?  result.map { |e| @formatter[ e ] } : result
  end

  def to_proc
    lambda { |i| 
      outs = @specs.map { |spec| spec[ i ] }
      editor[ i, outs ]
    }
  end  

end
```
#### 実行方法
```ruby fizzbuzz_main.rb ```

```ruby:fizzbuzz_main.rb
require "./fizzbuzz"

# Pattern 1 : (1..30)
FizzBuzz.new do |fizzbuzz|

  fizzbuzz.spec( :Fizz ) { |e| e % 3 == 0 }
  fizzbuzz.spec( :Buzz ) { |e| e % 5 == 0 }

  fizzbuzz.edit { |i, outs| 
    out = outs.join
    out.empty? ? i : out
  }
  
end.output do |e|
  puts e
end

# Pattern 2 : (31..69)
fizzbuzz = FizzBuzz.new(31, 69)
fizzbuzz.edit { |i, outs| 
  out = outs.join
  out.empty? ? i : out
}
fizzbuzz.spec( :B ) { |e| e % 5 == 0 }
fizzbuzz.spec( :F ) { |e| e % 3 == 0 }
result = fizzbuzz.output
puts result * " "

# Pattern 3 : (70..105)
FizzBuzz.new(70, 105) do |fizzbuzz|

  fizzbuzz.spec( :Pizz ) { |e| e % 3 == 0 }
  fizzbuzz.spec( :Quzz ) { |e| e % 5 == 0 }
  fizzbuzz.spec( :Razz ) { |e| e % 7 == 0 }

  fizzbuzz.edit { |i, outs| 
    out = outs.join
    out.empty? ? i : out
  }
  
  fizzbuzz.format { |e| puts e }
  
end.output
```