BundlerでFizzBuzz

今年もFizzBuzzの季節がやってまいりました。

FizzBuzzを書くことのできない言語を使えると口にすることはとても恥ずかしいことらしいので、きっとFizzBuzzを書くことのできないライブラリを使ってることも恥ずかしいことなのだろうと思います。

私も、ほとんどのライブラリはFizzBuzzしたことがありませんでした。このままではソーシャル転職をすることができません!将来のキャリアプランが台無しです。

そういえば最近、Ruby on Railsの世界ではBundlerというツールが流行っているらしいので、これを使ってFizzBuzzすることにしてみました。

Gemfileを用意する

$ cat > Gemfile
source 'https://rubygems.org'
gem 'rails'
^D

まずはGemfileを準備します。railsを入れるだけで色々入るので、ここではrailsを使っています。

bundle installを実行してみる

$ bundle install --path=vendor/bundle --binstubs
Fetching gem metadata from https://rubygems.org/.......
Installing rake (0.9.2.2) 
Installing i18n (0.6.0) 
Installing multi_json (1.3.6) 
Installing activesupport (3.2.7) 
Installing builder (3.0.0) 
Installing activemodel (3.2.7) 
Installing erubis (2.7.0) 
Installing journey (1.0.4) 
Installing rack (1.4.1) 
Installing rack-cache (1.2) 
Installing rack-test (0.6.1) 
Installing hike (1.2.1) 
Installing tilt (1.3.3) 
Installing sprockets (2.1.3) 
Installing actionpack (3.2.7) 
Installing mime-types (1.19) 
Installing polyglot (0.3.3) 
Installing treetop (1.4.10) 
Installing mail (2.4.4) 
Installing actionmailer (3.2.7) 
Installing arel (3.0.2) 
Installing tzinfo (0.3.33) 
Installing activerecord (3.2.7) 
Installing activeresource (3.2.7) 
Installing json (1.7.4) with native extensions 
Installing rack-ssl (1.3.2) 
Using bundler (1.1.5) 
Installing rdoc (3.12) 
Installing thor (0.15.4) 
Installing railties (3.2.7) 
Installing rails (3.2.7) 
Your bundle is complete! It was installed into ./vendor/bundle
Post-install message from rdoc:
Depending on your version of ruby, you may need to install ruby rdoc/ri data:

<= 1.8.6 : unsupported
 = 1.8.7 : gem install rdoc-data; rdoc-data --install
 = 1.9.1 : gem install rdoc-data; rdoc-data --install
>= 1.9.2 : nothing to do! Yay!

$ 

色々入りました。これでGemfile.lock及び.bundle/configファイルが生成されますので、今後は単純に bundle を実行するだけで同様のコマンドが実行されます。素敵なツールですね!

では早速、この出力結果をFizzBuzzにしちゃいましょう。

実行ファイルを作りましょ

# -*- encoding: utf-8 -*-

require 'bundler'
require 'bundler/cli'

module Bundler
  class UI
    class Shell
      @@count = 1
      FIZZ = "Fizz"
      BUZZ = "Buzz"
      FIZZBUZZ = "FizzBuzz"
      def tell_me(msg, color=nil, newline=nil)
        new_msg = ""
        msg.each_char do |ch|
          if @@count % 15 == 0
            new_msg += FIZZBUZZ
          elsif @@count % 5 == 0
            new_msg += BUZZ
          elsif @@count % 3 == 0
            new_msg += FIZZ
          else
            new_msg += @@count.to_s
          end
          @@count += 1
        end

        newline.nil? ? @shell.say(new_msg, color) : @shell.say(new_msg, color, newline)
      end
    end
  end
end

Bundler::CLI.start

こんな感じのプログラムを、fizzbuzz.rb と名前をつけて置いておきます。そしておもむろに実行!すると…

$ ruby1.9.1 fizzbuzz.rb 
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz1617Fizz19BuzzFizz

2223FizzBuzz26Fizz2829FizzBuzz3132Fizz34BuzzFizz3738FizzBuzz

41Fizz4344FizzBuzz4647Fizz49BuzzFizz5253FizzBuzz56Fizz5859FizzBuzz6162Fizz64Buzz

Fizz6768FizzBuzz71Fizz7374FizzBuzz7677Fizz79BuzzFizz8283FizzBuzz86Fizz8889FizzBuzz9192Fizz

94BuzzFizz9798FizzBuzz101Fizz103104FizzBuzz106107Fizz109BuzzFizz112113FizzBuzz

116Fizz118119FizzBuzz121122Fizz124BuzzFizz127128FizzBuzz131Fizz133134FizzBuzz136137Fizz139BuzzFizz

142143FizzBuzz146Fizz148149FizzBuzz151152Fizz154BuzzFizz157158FizzBuzz161Fizz

163164FizzBuzz166167Fizz169BuzzFizz172173FizzBuzz176Fizz178179FizzBuzz181182Fizz184

BuzzFizz187188FizzBuzz191Fizz193194FizzBuzz196197Fizz199BuzzFizz202203

FizzBuzz206Fizz208209FizzBuzz211212Fizz214BuzzFizz217218FizzBuzz221Fizz223224FizzBuzz226

227Fizz229BuzzFizz232233FizzBuzz236Fizz238239FizzBuzz241242Fizz244BuzzFizz247248FizzBuzz

251Fizz253254FizzBuzz256257Fizz259BuzzFizz262263FizzBuzz266Fizz268269

FizzBuzz271272Fizz274BuzzFizz277278FizzBuzz281Fizz283284FizzBuzz286287Fizz

289BuzzFizz292293FizzBuzz296Fizz298299FizzBuzz301302Fizz304BuzzFizz307308FizzBuzz311Fizz

313314FizzBuzz316317Fizz319BuzzFizz322323FizzBuzz326Fizz328329FizzBuzz331332Fizz334BuzzFizz337

338FizzBuzz341Fizz343344FizzBuzz346347Fizz349BuzzFizz352353FizzBuzz356Fizz358359FizzBuzz361

362Fizz364BuzzFizz367368FizzBuzz371Fizz373374FizzBuzz376377Fizz379BuzzFizz382383Fizz

Buzz386Fizz388389FizzBuzz391392Fizz394BuzzFizz397398FizzBuzz401Fizz403404FizzBuzz406407

Fizz409BuzzFizz412413FizzBuzz416Fizz418419FizzBuzz421422Fizz424BuzzFizz

427428FizzBuzz431Fizz433434FizzBuzz436437Fizz439BuzzFizz442443FizzBuzz446Fizz448449FizzBuzz451452Fizz

454BuzzFizz457458FizzBuzz461Fizz463464FizzBuzz466467Fizz469BuzzFizz472

473FizzBuzz476Fizz478479FizzBuzz481482Fizz484BuzzFizz487488FizzBuzz491Fizz493494

FizzBuzz496497Fizz499BuzzFizz502503FizzBuzz506Fizz508509FizzBuzz511512Fizz514BuzzFizz517518FizzBuzz521

Fizz523524FizzBuzz526527Fizz529BuzzFizz532533FizzBuzz536Fizz538539FizzBuzz541542Fizz544BuzzFizz547548FizzBuzz

551Fizz553554FizzBuzz556557Fizz559BuzzFizz562563FizzBuzz566Fizz568569

FizzBuzz571572Fizz574BuzzFizz577578FizzBuzz581Fizz583584FizzBuzz586587Fizz589BuzzFizz592

593FizzBuzz596Fizz598599FizzBuzz601602Fizz604BuzzFizz607608FizzBuzz611Fizz613614

FizzBuzz616617Fizz619BuzzFizz622623FizzBuzz626Fizz628629FizzBuzz631632

Fizz634BuzzFizz637638FizzBuzz641Fizz643644FizzBuzz646647Fizz649BuzzFizz652

653FizzBuzz656Fizz658659FizzBuzz661662Fizz664BuzzFizz667668FizzBuzz671Fizz673674FizzBuzz

676677Fizz679BuzzFizz682683FizzBuzz686Fizz688689FizzBuzz691692Fizz694Buzz

Fizz697698FizzBuzz701Fizz703704FizzBuzz706707Fizz709BuzzFizz712713FizzBuzz716Fizz718719FizzBuzz721722Fizz724BuzzFizz727728FizzBuzz731Fizz733734FizzBuzz736737Fizz739BuzzFizz742743FizzBuzz746Fizz748749FizzBuzz751752Fizz754BuzzFizz757
$

わぁい!出力がFizzBuzz化されたよ!

でも、FizzBuzzってそもそもどういう意味なの…

FizzBuzzって何のことか意味がわかりませんから、先ほどの変数の一部をより親しみやすい文字列にしましょう。また、数字ではなく元の英字そのものを取ると、より見やすくなるかも知れません。

$ diff fizzbuzz.rb fizzbuzz_akari.rb 
10,12c10,12
<       FIZZ = "Fizz"
<       BUZZ = "Buzz"
<       FIZZBUZZ = "FizzBuzz"
---
>       FIZZ = "ゆるゆり"
>       BUZZ = "はっじまっるよー"
>       FIZZBUZZ = "\アッカリーン/"
23c23
<             new_msg += @@count.to_s
---
>             new_msg += ch
$

…というマイナーチェンジを行えば、以下の出力が得られます。

$ ruby1.9.1 fizzbuzz_akari.rb
Usゆるゆりnはっじまっるよーゆるゆりraゆるゆりはっじまっるよー ゆるゆり0.\アッカリーン/.2ゆるゆり2はっじまっるよーゆるゆり

Usゆるゆりはっじまっるよーgゆるゆりi1\アッカリーン/n ゆるゆり0はっじまっるよーゆるゆり.0ゆるゆりはっじまっるよー

Uゆるゆりin\アッカリーン/ mゆるゆりlはっじまっるよーゆるゆり_jゆるゆりはっじまっるよーnゆるゆり(1\アッカリーン/3.ゆるゆり)はっじまっるよー

ゆるゆりsiゆるゆりはっじまっるよー ゆるゆりct\アッカリーン/veゆるゆりuはっじまっるよーゆるゆりorゆるゆりはっじまっるよー(ゆるゆり.2\アッカリーン/7)ゆるゆり

Uはっじまっるよーゆるゆりngゆるゆりはっじまっるよーuゆるゆりld\アッカリーン/r ゆるゆり3はっじまっるよーゆるゆり.0ゆるゆりはっじまっるよー

Uゆるゆりin\アッカリーン/ aゆるゆりtはっじまっるよーゆるゆりemゆるゆりはっじまっるよーeゆるゆり (\アッカリーン/.2ゆるゆり7はっじまっるよーゆるゆり

Usゆるゆりはっじまっるよーgゆるゆりer\アッカリーン/biゆるゆり はっじまっるよーゆるゆり.7ゆるゆりはっじまっるよー)ゆるゆり

Us\アッカリーン/ngゆるゆりjはっじまっるよーゆるゆりrnゆるゆりはっじまっるよー ゆるゆり1.\アッカリーン/.4ゆるゆり 
はっじまっるよーゆるゆりinゆるゆりはっじまっるよーrゆるゆりck\アッカリーン/(1ゆるゆり4はっじまっるよーゆるゆり) 
ゆるゆりはっじまっるよーiゆるゆりg \アッカリーン/acゆるゆり-はっじまっるよーゆるゆりchゆるゆりはっじまっるよー(ゆるゆり.2\アッカリーン/ 
Uゆるゆりiはっじまっるよーゆるゆり rゆるゆりはっじまっるよーkゆるゆりte\アッカリーン/t ゆるゆり0はっじまっるよーゆるゆり.1ゆるゆりはっじまっるよー

Uゆるゆりin\アッカリーン/ hゆるゆりkはっじまっるよーゆるゆり(1ゆるゆりはっじまっるよー.ゆるゆり) 
\アッカリーン/siゆるゆりgはっじまっるよーゆるゆりilゆるゆりはっじまっるよー(ゆるゆり.3\アッカリーン/3)ゆるゆり

Uはっじまっるよーゆるゆりngゆるゆりはっじまっるよーpゆるゆりoc\アッカリーン/etゆるゆり はっじまっるよーゆるゆり.1ゆるゆりはっじまっるよー)ゆるゆり

Us\アッカリーン/ngゆるゆりaはっじまっるよーゆるゆりioゆるゆりはっじまっるよーaゆるゆりk \アッカリーン/3.ゆるゆり.はっじまっるよーゆるゆり 
Uゆるゆりはっじまっるよーnゆるゆり m\アッカリーン/meゆるゆりtはっじまっるよーゆるゆりesゆるゆりはっじまっるよー1ゆるゆり19\アッカリーン/ 
Uゆるゆりiはっじまっるよーゆるゆり pゆるゆりはっじまっるよーyゆるゆりlo\アッカリーン/ (ゆるゆり.はっじまっるよーゆるゆり3)ゆるゆり

はっじまっるよーsゆるゆりng\アッカリーン/trゆるゆりeはっじまっるよーゆるゆりp ゆるゆりはっじまっるよー.ゆるゆり.1\アッカリーン/) 
ゆるゆりsはっじまっるよーゆるゆりg ゆるゆりはっじまっるよーiゆるゆり (\アッカリーン/.4ゆるゆり4はっじまっるよーゆるゆり

Usゆるゆりはっじまっるよーgゆるゆりac\アッカリーン/ioゆるゆりmはっじまっるよーゆるゆりleゆるゆりはっじまっるよー(ゆるゆり.2\アッカリーン/7)ゆるゆり

Uはっじまっるよーゆるゆりngゆるゆりはっじまっるよーrゆるゆりl \アッカリーン/3.ゆるゆり.はっじまっるよーゆるゆり 
Uゆるゆりはっじまっるよーnゆるゆり t\アッカリーン/inゆるゆりoはっじまっるよーゆるゆり0.ゆるゆりはっじまっるよー3ゆるゆり) 
\アッカリーン/siゆるゆりgはっじまっるよーゆるゆりctゆるゆりはっじまっるよーeゆるゆりec\アッカリーン/rdゆるゆり(はっじまっるよーゆるゆり2.ゆるゆりはっじまっるよー 
ゆるゆりsi\アッカリーン/g ゆるゆりcはっじまっるよーゆるゆりveゆるゆりはっじまっるよーsゆるゆりur\アッカリーン/e ゆるゆり3はっじまっるよーゆるゆり.7ゆるゆりはっじまっるよー

Uゆるゆりin\アッカリーン/ jゆるゆりoはっじまっるよーゆるゆり(1ゆるゆりはっじまっるよー.ゆるゆり) 
\アッカリーン/siゆるゆりgはっじまっるよーゆるゆりacゆるゆりはっじまっるよーsゆるゆりl \アッカリーン/1.ゆるゆり.はっじまっるよーゆるゆり 
Uゆるゆりはっじまっるよーnゆるゆり b\アッカリーン/ndゆるゆりeはっじまっるよーゆるゆり(1ゆるゆりはっじまっるよー.ゆるゆり) 
\アッカリーン/siゆるゆりgはっじまっるよーゆるゆりdoゆるゆりはっじまっるよー(ゆるゆり.1\アッカリーン/) 
ゆるゆりsはっじまっるよーゆるゆりg ゆるゆりはっじまっるよーoゆるゆり (\アッカリーン/.1ゆるゆり.はっじまっるよーゆるゆり 
Uゆるゆりはっじまっるよーnゆるゆり r\アッカリーン/ilゆるゆりiはっじまっるよーゆるゆり (ゆるゆりはっじまっるよー2ゆるゆり7)\アッカリーン/

Usゆるゆりnはっじまっるよーゆるゆりraゆるゆりはっじまっるよーsゆるゆり(3\アッカリーン/2.ゆるゆり)はっじまっるよー

ゆるゆりouゆるゆりはっじまっるよーbゆるゆりnd\アッカリーン/e ゆるゆりsはっじまっるよーゆるゆりomゆるゆりはっじまっるよーeゆるゆりe!\アッカリーン/Itゆるゆりwはっじまっるよーゆるゆり iゆるゆりはっじまっるよーtゆるゆりll\アッカリーン/d ゆるゆりnはっじまっるよーゆるゆり .ゆるゆりはっじまっるよーeゆるゆりdo\アッカリーン//bゆるゆりnはっじまっるよーゆるゆりe
$

やった!これでFizzBuzzできますって職歴に書ける!

最後に、注意事項

以上の手順を踏めば比較的問題ないですが、bundle install --path=vendorを実行する手順を抜かしたりすると、システムワイドにgemがインストールされたりするので気をつけてください。