たのしいRuby(第2版) 「はじめてのRuby」〜制御構造 繰り返し〜

■これは「たのしいRuby 第2版」を元にしています。
http://www.amazon.co.jp/%E3%81%9F%E3%81%AE%E3%81%97%E3%81%84Ruby-%E7%AC%AC2%E7%89%88-Ruby%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%B0%97%E8%BB%BD%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E9%AB%98%E6%A9%8B-%E5%BE%81%E7%BE%A9/dp/4797336617/ref=pd_sim_b_img_6/250-4677527-6737860

概要

 同じこと、または同じようなことを何度か繰り返したい場合があります。繰返しを行う方法を3つ紹介しましょう。

やってみるのは、

  • while
  • times
  • each

の3つです。


while文

 while文は、繰り返しを行うための基本的な構文です。なお、doは省略することもできます。

while 繰り返し続ける条件 do
 繰り返したい処理
end

ふむ。やってみましょう。

  • プログラム
i = 1
while i <= 10
 p i
 i = i + 1
end
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
1
2
3
4
5
6
7
8
9
10

変数 i が 10以上になるまで繰り返しましたね。
whileは無限ループに注意です。繰り返し続ける条件がずっと満たされているとずーーーーっと繰り返していますから。

「条件を満たすまで繰り返す」ということですから、
「クイズが正解するまで繰り返す」とか
「西暦2100年まで繰り返す」とか
「何か成功するまで繰り返す」とか
いろいろと使えますね。


until文

if文に対してunless文があったように、while文に対してもuntil文があります。until文は、構文の見た目はwhile文と同じですが、条件の判定が逆になります。つまり、その条件を満たしていない場合に繰返しを行います。


until 条件 do
 繰り返したい処理
end

なるほどー。とりあえずやってみましょう。

  • プログラム
i = 1
until 10 <= i
p i
i = i + 1
end
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
1
2
3
4
5
6
7
8
9

おおぉ、なりましたね。

timesメソッド

回数が決まっているときは、「times」というメソッドを使うと簡単です。

繰り返す回数.times {
 繰り返したい処理
}

ふむ。やってみましょう。

  • プログラム
100.times {
 print "「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」\n"
}
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」

「う…うろたえるんじゃあないッ! ドイツ軍人はうろたえないッ!」
↑これが100回も繰り返されているページをはじめてみましたwww
なかなか貴重ではないかと思われます。

 timesメソッドいテレーたと呼ばれるメソッドです。イテレータiterator)は、他の言語ではあまり見られないRubyの特徴的な要素です。
スペルからも分かるように「繰り返す(iterate)もの(-or)」という意味です。オペレータ(operator)が「演算(operate)するもの」として「演算子」と呼ばれるものをまねするなら、さしずめ「繰り返し子」「反復子」というところでしょうか。
 その名の通り、繰返しを行うためのメソッドです。
 Rubyはtimesメソッド以外にも数多くのイテレータを提供しています。イテレータの代表はeachメソッドです。eachメソッドについては、第2章で配列やハッシュと一緒に紹介します。

まぁ、せっかくなのでeachも少し触ってみましょう。

each

このメソッドは「順番に要素を取り出し、その要素を使って何らかの処理をする」ためのイテレータで、Rubyのいろいろなクラスで定義されています。
- たのしいRuby P379

プログラミング言語 Ruby リファレンスマニュアル

各要素に対してブロックを評価します。self を返します。

例:
#1、2、3が順番に表示される
[1,2,3].each do |i|
p i
end

まだ、配列などをやっていないので分かりにくいですよね・・・。
とりあえず、配列に定義されているeachの実行結果をみてみましょう。

  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
1
2
3

ふむ。順番に出力されましたね。
詳しくは後日行います。



環境

C:\enjoy_ruby>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

たのしいRuby(第2版) 「はじめてのRuby」〜制御構造の概要とif 〜

■これは「たのしいRuby 第2版」を元にしています。
http://www.amazon.co.jp/%E3%81%9F%E3%81%AE%E3%81%97%E3%81%84Ruby-%E7%AC%AC2%E7%89%88-Ruby%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%B0%97%E8%BB%BD%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E9%AB%98%E6%A9%8B-%E5%BE%81%E7%BE%A9/dp/4797336617/ref=pd_sim_b_img_6/250-4677527-6737860

制御構造

 プログラミング言語には、制御構造というものがあります。
 これは、何かの条件によって、プログラムの実行順序を変えたり、プログラムの一部を実行させなかったりするための仕組みです。

ふむ。


プログラミング言語 Ruby リファレンスマニュアル


制御構造の分類

制御構造を大雑把に分類すると次のようになります。

 ・逐次処理 : プログラムを書かれた通りに、先頭から順に実行する
 ・条件判断 : ある条件が成り立つ場合は○○を、そうでない場合は、××を実行する
 ・繰り返し  : ある条件が成り立つ間、○○を繰り返し実行する
 ・例外処理 : 何か例外が発生した場合には、○○を実行する

ふむ。では、1つ1つ見ていきましょう。


逐次処理

 逐次処理というのは、通常の処理のことです。特に何も指定していない場合、プログラムは書かれた順に実行されます。

これ、意外と重要かと思います。

僕、プログラムをやり始めた当初、とある瞬間に「あ!!プログラムって上から下に順番に実行されるんだ!!」と気づきwwwwだいぶ楽になったのを覚えています。
それにしても、やり始めの練習プログラムで、上から下に流れなかったらどういうプログラムを書いて、どういう風に理解していたのでしょうかwwwwいまでは不明ですwwww


条件判断

 ある条件によって挙動が変わるプログラムを作るには、if文を使います。if文の構文は、以下のようになります。

if 条件 then
実行したい処理
end

条件には、値がtrueまたはfalseとなる式を書くのが一般的です。

ふむふむ。

では、「値がtrueまたはfalseとなる式」とはなんでしょうか。

 2つの値を比較して、一致すればtrue、一致しなければfalse、などが条件にあたります。
 数値の場合、たとえば大小関係の比較には、等号や不等号を使います。Rubyでは、「=」は代入のための記号として使われるので、一致するかどうか調べるには「=」を2つ並べた記号「==」を使います。また、「≦」と「≧」には、「<=」と「>=」を使います。
 このような比較の結果はtrueまたはfalseとなります。もちろん、trueはその条件が成り立っている場合、falseは成り立っていない場合です。

なるほど、条件がtrueまたはfalseになるのかやってみましょう。

  • プログラム
p (2 == 2)
p (1 == 2)
p (3 > 1)
p (3 > 3)
p (3 >= 3)
p (3 < 1)
p (3 < 3)
p (3 <= 3)
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
true
false
true
false
true
false
false
true


おお。なりましたねー。
では、これを使って if 文を書いてみましょう。

  • プログラム
a = 9

#例1
if a < 10
print "aは10より小さいです!\n"
end

#例2
if a > 1
print "aは1より大きいです!\n"
end

#例3
if a > 10
print "aは10より大きくない!\n"
end

上記のプログラムの例1と例2はtrueを返すので実行されます、例3の条件はfalseを返すので実行はされないはずです。実行してみましょう。

  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
aは10より小さいです!
aは1より大きいです!

ちゃんと条件はあってますね。trueの部分だけ実行されました。


文字列比較

 文字列も比較できます。この場合も「==」を使います。同じ文字列ならtrue、異なる文字列ならfalseを返します。

ふむ。やってみましょう。

  • プログラム
p ("Ruby" == "Ruby")
p ("Ruby" == "ruby")
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
true
false


なりましたね。

 値が異なっていることを判断するには、「!=」を使います。これは「≠」の意味ですね。

ふむ。やってみましょう。

  • プログラム
p ("Ruby" != "Ruby")
p ("Ruby" != "ruby")
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
false
true

「==」とは逆の結果になりましたね。


条件判断文を書いてみよう

  • プログラム
a = 20
if a >= 10 then
  print("bigger\n")
end

if a <= 9 then
  print("smaller\n")
end
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
bigger

変数aは10より大きいですから結果は"bigger"ですね。


thenは省略できる

thenは省略することもできます。

やってみましょう。

  • プログラム
a = 20
if a >= 10
  print("bigger\n")
end

if a <= 9
  print("smaller\n")
end
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
bigger

大丈夫ですね。
ちなみに、thenが書いてあるプログラムはほとんどみないですね・・・。


else

 また、条件に一致するときとしないときで違う動作をさせたい場合は、elseを使います。以下のような構文になります。

if 条件 then
条件が成り立ったときに実行したい処理
else
条件が成り立たなかったときに実行したい処理
end

これを使って、先ほどの条件判断文を書き直すと以下のようになります。

  • プログラム
a = 20

if a >= 10
  print("bigger\n")
else
  print("smaller\n")
end
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
bigger

もっとif

if はtrueとfalseの条件しか判断できないのでしょうか。
そんなことはありません。

こちらに、
プログラミング言語 Ruby リファレンスマニュアル

Ruby では false または nil だけが偽で、それ以外は 0 や空文 字列も含め全て真です。

つまり、

  • プログラム
if false

else
  print("ifでflaseは為\n")
end

if nil

else
  print("ifでnilも為\n")
end

if 0
  print("Rubyは0も真\n")
end

if "a"
  print("文字列も真\n")
end

if 1
  print("数値も真\n")
end
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
helloruby.rb:19: warning: string literal in condition
ifでflaseは為
ifでnilも為
Rubyは0も真
文字列も真
数値も真

となります。

ちなみに、PHPだと0は為になります。他の言語を触っている人はRubyの仕様をしっかりと把握しましょう。

if "文字列" だと「warning: string literal in condition」と注意が出るようですね。


elsif

プログラミング言語 Ruby リファレンスマニュアル

 Ruby では if を繋げるのは elsif であり、else if (C のように)でも elif(sh のように)でもないことに注意してください。

以下の例をみてみましょう。

  • プログラム
a = 2

if a==1
  print("aは1です!")
elsif a==2
  print("aは2です!")
else
  print("aは1,2意外です!")
end
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
aは2です!


このように複数の条件で分岐することも可能です。


if 修飾子

プログラミング言語 Ruby リファレンスマニュアル

文法:
式 if 式

右辺の条件が成立する時に、左辺の式を評価してその結果を返します。 条件が成立しなければ nil を返します。

プログラム例

  • プログラム
def if_nil
"" if false
end

print "ifが成立すると出力\n" if true
p if_nil
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
ifが成立すると出力
nil

※「条件が成立しなければ nil 」がちゃんと返るか実験するために、メソッド化しています。


ちゃんと出力されましたね。




※条件分岐はif以外にも unless case があります。これは別途やります。
プログラミング言語 Ruby リファレンスマニュアル


環境

C:\enjoy_ruby>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

RMagickとRubyGemsのバージョンの関係について

what

RMagickはRubyGemsのバージョンに大きく左右されるというお話。

プログラミング言語 Ruby リファレンスマニュアル


今回の現象に気づいたきっかけ

ImageMagickRMagicを使い、Rubyからイメージデータを操作していたのだが、gem update --system をして gems自身をアップデートしたら、動かなくなった・・・orz



RubyGemsのREADMEを読んで、RubyGemsの対応バージョンを知る

http://rubyforge.org/frs/?group_id=12&release_id=8170から rmagick-1.13.0-IM-6.2.9-0-win32.zip をダウンロード&解凍します。その中にある、README.html を読んでみると。

This distribution comes in the form of a Rubygem, since I firmly belive that is the way to go for distribution of ruby libraries. You should have a working copy of rubygems, which can be downloaded from rubygems.rubyforge.org.
Oh, and erm..

    gem --version
should yield

    0.9.0
or higher. Just do that gem update --system once in a while.

と書いてありますが・・・
http://rubyforge.org/frs/?group_id=167
こちらの、
1.8.6-26 Release Candidate 1 
1.8.6-26 Release Candidate 2
1.8.6-26 Final Release
に付属しているRubyGems0.9.4ではうまく動きません・・・orz

1.8.6では 1.8.6.-25 の RubyGems0.9.2 だとうまく動くようです。


「0.9.0 or higher」は嘘っぱちですか(´・ω・`)



動かないことを実験

  • 実験1

1.8.6-26 Release Candidate 1 
1.8.6-26 Release Candidate 2
1.8.6-26 Final Release
の場合。

C:\Image\test.gif というイメージデータがあるのが前提です。

C:\Rails_app>ruby script/console
Loading development environment.
>> original = Magick::Image.read("C:\\images\\test.gif").first
>> w,h = 100,50
=> [100, 50]
>> resized = original.resize_to_fit(w,h)
NoMethodError: undefined method `resize_to_fit' for #<Magick::Image:0x4966ec4>
       from (irb):5

再現した。たしかに、このオブジェクトにはresize_to_fitというメソッドがない。


  • 実験2

1.8.6-25
の場合。

C:\Image\test.gif というイメージデータがあるのが前提です。

C:\Rails_app>ruby script/console
Loading development environment.
>> original = Magick::Image.read("C:\\images\\test.gif").first
>> w,h = 100,50
=> [100, 50]
>> resized = original.resize_to_fit(w,h)
>>

成功。ちゃんとサイズが変更されたイメージが生成されている。何が違うんでしょうね・・・。



RubyGemsのバージョンダウングレードの方法

うまい方法が見つからなかったのですが・・・。
gem update --system でアップデートすると、 gem list に rubygems-update というのができるので、それを uninstall すればいいのかと思い、gem uninstall rubygems-update やったのですがバージョンは戻りません。うう。


ということで、Rubyを再インストール、ライブラリも再インストール・・・しかないのか?RubyGems自身のバージョンを戻す方法は・・・。



参考

http://docs.rubygems.org/read/chapter/5
RMagickをインストールしてみる(Windows) - Katawara.*

上記を見ると、RubyGemsとrmagickのバージョンには関係があるのがわかります。
しかし、RubyGemsというのは、パッケージ管理システムじゃないのでしょうか。。なんでこんなにライブラリの動きに影響が・・・。


RubyGemsは gem update --system と 直接ダウンロードして ruby setup.rb を実行するのとでは違うのか?

OS : Windows XP
C:\>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]
C:\>gem -v
0.9.4
Rails : 1.2.3
RMagick-1.13.0-win32
ImageMagick-6.2.9-0-Q8-windows

※上記の環境は、2007-9-17 に構築した環境ですが、当時はRuby 1.8.6-25 をDL&インストールして、 gem update --system をやると gem 0.9.4 になりました。これだと、動くのです。しかし、上記の実験のように、1.8.6-26 Release Candidate 1 、1.8.6-26 Release Candidate 2、1.8.6-26 Final Release に含まれる gem 0.9.4 だと動かないのです。
※また、Ruby 1.8.6-25 をダウンロードして、RubyGems 0.9.4 をダウンロードして setup.rb を実行して gem のバージョンを 0.9.4 にしても動かないのです。違いは、gem update --system でアップデートしたか、 setup.rb でアップデートしたかの違いです。


同じバージョンなのに、なんで違うのでしょうか・・・。
もっと新しいの使えってことでしょうか。。

たのしいRuby(第2版) 「はじめてのRuby」〜コメントを書く〜

■これは「たのしいRuby 第2版」を元にしています。
http://www.amazon.co.jp/%E3%81%9F%E3%81%AE%E3%81%97%E3%81%84Ruby-%E7%AC%AC2%E7%89%88-Ruby%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%B0%97%E8%BB%BD%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E9%AB%98%E6%A9%8B-%E5%BE%81%E7%BE%A9/dp/4797336617/ref=pd_sim_b_img_6/250-4677527-6737860

コメントを書く

 プログラム中には、コメントを書くことができます。コメントは、プログラム中に書かれていても、直接プログラムとしては扱われません。つまり、プログラムの実行には何の関係もないもの、と言うことです。
 「どうしてプログラムの中に、実行とは関係のない余計なものを書くのだろう?」と思われるかもしれません。確かに一度書いて実行すればそれっきり、というプログラムであれば、コメントは特に必要ないでしょう。しかし、一度書いたプログラムを何度も使いまわすことも少なくありません。そのようなときに、

 ・プログラムの名前や作者、配布条件などの情報
 ・プログラムの説明

などを書いておくために、コメントが使われます。

いろいろプログラムを見ていると、上記の他にもコメントがあったりします。「モジュールの使い方」であったり、「ここはリファレンスはありません」などといったものもあります。
適度に書いてあると、他の人が見た時に、分かりやすいという利点があります。

ただ、書きすぎは良くないのかなぁと思います。
基本的にはプログラムを読めば全て分かるので、読んだ方が良いと思います。それが真実ですので。

適度が一番。


コメントの書き方

 コメントを表す記号は「#」です。行頭に「#」があれば、1行まるまるコメントになります。行の途中に「#」があれば、「#」の部分から行末までがすべてコメントになります。また、行頭から始まる「=begin」と「=end」で囲まれた部分もコメントになります。これは、プログラムの先頭や最後で、長い説明を記しておくのに重宝します。

ふむ。ではやってみましょう。

  • プログラム
=begin
「たのしいRuby 第2版」サンプル
コメントの使い方の例
 2006/06/26 作成
 2006/07/01 一部コメントを追加
=end
x = 10    # 横
y = 20    # 縦
z = 30    # 高さ
# 表面積と体積を計算する。
are = (x*y + y*z + z*x) * 2
volume = x * y * z
# 出力する
print("表面積", are, "\n")
print("体積", volume, "\n")
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
楓ハ積2200
体積6000

コメントはまったく無視されて表示されましたね。

コメントは、先ほどあげた目的以外にも、「この行を処理を一時的に実行させないようにする」といったことに使います。

注意:
C言語のコメントのように、行の途中だけをコメントにするような書き方はありません。行末まで必ずコメントになります。

あ、これけっこう使います。プログラムを作成しているときも使えますし、なにかと便利ですが、
バージョン管理されているプログラムをコミットするときに、一部コードがコメントアウトするのはムダな場合があります。バージョンをさかのぼれば発見できるわけですから。





環境

C:\enjoy_ruby>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

たのしいRuby(第2版) 「はじめてのRuby」〜変数〜

■これは「たのしいRuby 第2版」を元にしています。
http://www.amazon.co.jp/%E3%81%9F%E3%81%AE%E3%81%97%E3%81%84Ruby-%E7%AC%AC2%E7%89%88-Ruby%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%B0%97%E8%BB%BD%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E9%AB%98%E6%A9%8B-%E5%BE%81%E7%BE%A9/dp/4797336617/ref=pd_sim_b_img_6/250-4677527-6737860

変数

プログラミングに欠かせない要素として変数があります。変数とは、「もの」につける名札のようなものです。
オブジェクトに名札をつけるには、

 変数名 = オブジェクト

と書きます。このことを「変数にオブジェクトを代入する」といいいます。

ふむ。とりあえず、やってみましょう。

  • プログラム
name = "japanrock"
age  = 30

print "name = ", name ,"\n"
print "age  = ", age  ,"\n"

p name.class
p age.class
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
name = japanrock
age  = 30
String
Fixnum

name という変数に "japanrock" というStringのオブジェクトを代入してそれをprintで出力していますね。
同じように、age という変数に 30 というFixnumのオブジェクトをだ乳してそれをprintで出力しています。


変数の利用例として、直方体の表面積と体積を求めるプログラムを見てみましょう。

はーい。

  • プログラム
x = 10
y = 20
z = 30
area = (x*y + y*z + z*x) * 2
volume = x * y * z
print("表面積=", area, "\n")
print("体積=", volume, "\n")
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
楓ハ積=2200
体積=6000

計算結果は正しいですが、「表面積」という日本語が文字化けております・・・。しかし、今回は変数の回なので無視します・・。

変数をまったく使わなければ、

  • プログラム
print("表面積=",(10*20 + 20*30 + 30*10) * 2, "\n")
print("体積=",10*20*30, "\n")
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
楓ハ積=2200
体積=6000

といったプログラムになってしまいます。これでは値を1つ変更するために何ヶ所も修正しなければいけません。この例はたったの2行なのでたいしたことはありませんが、ちょっと大きなプログラムになると、そのような変更をきちんと行うのは大変な手間となります。

はい。そうなんです。これとっても重要です。うまくやれば1つの変更で済むのですが、100個も200個もあると、発狂しそうになります。まぁ、エディタにグレップ機能があって一斉置換なんて方法もあるのですが、10とか20とかのよくありがちな数字だったりすると、一斉置換ではうまくいかない場合があります。なので、変数に入れておくと目的のものだけを間違いなく修正できるので便利です。


名前重要

また、変数には、値が何を表しているのかを明確にするという意味もあります。したがって、わかりやすい名前を付けることが大切です。たとえば、

  • プログラム
hoge = "japanrock"
fuga = 30
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
hoge = japanrock
fuga = 30

たしかに、表示されましたが、変数名が何を表しているのか分かりにくいですね。
以下と比較してみましょう。

  • プログラム
name = "japanrock"
age  = 30

print "name = ", name ,"\n"
print "age  = ", age  ,"\n"
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
name = japanrock
age  = 30

"japanrock"は名前を表し、30は年齢を表しているというのがよく分かります。

変数名はプログラムの可視性を保つのにとっても、重要です。一度名前を付けると、いろいろな場所で使われていくので、変更がやっかいです。
変数名に限らず、メソッド名やクラス名なども同じことが言えます。

名前を付けるときは、少々時間がかかってもよいので、分かりやすく的確な名前をつけましょう。


おまけ

また、変数は以下のようにも代入できます。

  • プログラム
name, age, address = "japanrock", 30, "Tokyo"

print "name = ", name ,"\n"
print "age  = ", age  ,"\n"
print "address  = ", address  ,"\n"
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
name = japanrock
age  = 30
address  = Tokyo

変数の種類

変数には種類があります。


詳しくは、後日クラスやメソッドなどのところで行います。


プログラミング言語 Ruby リファレンスマニュアル



ちなみに、今回の例でりようした変数はすべてローカル変数です。


環境

C:\enjoy_ruby>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

たのしいRuby(第2版) 「はじめてのRuby」〜数学的な関数〜

■これは「たのしいRuby 第2版」を元にしています。
http://www.amazon.co.jp/%E3%81%9F%E3%81%AE%E3%81%97%E3%81%84Ruby-%E7%AC%AC2%E7%89%88-Ruby%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%B0%97%E8%BB%BD%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E9%AB%98%E6%A9%8B-%E5%BE%81%E7%BE%A9/dp/4797336617/ref=pd_sim_b_img_6/250-4677527-6737860

数学的な関数

 四則演算以外にも、平方根や、三角関数の「sin」「cos」、指数関数などの数学的な関数が利用できます。ただし、その場合、プログラムの最初の方に「include Math」というおまじないを入れる必要があります。
 sinはsinメソッド、平方根はsqrtメソッドで求めます。メソッドを実行すると、計算した結果を得ることができます。このことをメソッドが値を返すといい、得られる値のことを返り値といいます。

うはー。中学の授業きたーwww小学校だっけ?www
サイン、コサイン、タンジェントとかもう忘れたwwwwww
「かえりち」と打つと「返り血」と変換されるので困りますwwww s/返り血/返り値


三角関数 - Wikipedia



まぁ、とにかく実行してみましょう。

  • プログラム
include Math
print "sin(3.1415) = ", sin(3.1415), "\n"
print "sqrt(10000) = ", sqrt(10000), "\n"
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
sin(3.1415) = 9.26535896604902e-005
sqrt(10000) = 100.0

えーと・・・いろいろと突っ込みたいですね・・・w



とりあえず、include Mathがなかった場合どうなるのかやってみましょう。

  • プログラム
include Math
print "sin(3.1415) = ", sin(3.1415), "\n"
print "sqrt(10000) = ", sqrt(10000), "\n"
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
helloruby.rb:1: undefined method `sin' for main:Object (NoMethodError)

NoMethodError ですね。


「9.26535896604902e-005」という表記について

1番目のsinの答えである「9.26535896604902e-005」ですが、これは、極端に大きいか、あるいは極端に小さい数を表す時に便利な表記方法です。「(少数) e (整数)」と表示された時は、「(少数) * (10の整数乗)」の値、と解釈してください。この例の場合、「9.26535896604902 * (10の-5乗)」ということになるので、つまりは0.0000926535896604902 という数字を表しています。

なるほどー。

e-005等のclassは何になるのでしょう。

  • プログラム

print 2e-005.class

  • 実行結果

Float

でした。


「include Math」 ついて

「Math」というのは、Mathモジュールを表す定数です。「include Math」というのは、Mathモジュールに属する関数を直接利用できるようにするものです。includeしない場合には、「Math.sin(3.14)」などと書けば、Mathモジュールの関数が利用できます。先ほどのプログラムを、「include」を使わないで書きなおすと、以下のようになります。

print "sin(3.1415) = ", Math.sin(3.1415), "\n"
print "sqrt(10000) = ", Math.sqrt(10000), "\n"

なるほど、やってみましょう。

  • プログラム
print "sin(3.1415) = ", Math.sin(3.1415), "\n"
print "sqrt(10000) = ", Math.sqrt(10000), "\n"
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
sin(3.1415) = 9.26535896604902e-005
sqrt(10000) = 100.0


ふむ。大丈夫ですね。


Mathモジュールをもうちょっとつっこむ

プログラミング言語 Ruby リファレンスマニュアル

円周率
  • プログラム
print Math::PI
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
3.14159265358979
自然対数の底
  • プログラム
print Math::E
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
2.71828182845905

環境

C:\enjoy_ruby>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

たのしいRuby(第2版) 「はじめてのRuby」〜数値の表示と計算〜

■これは「たのしいRuby 第2版」を元にしています。
Amazon CAPTCHA

Rubyのプログラムでは、整数や小数(浮動小数点数)を、自然な形で扱うことができます。

数値の表示

Rubyでは文字列は文字列オブジェクトという形になっている」と説明しました。同じように、数値も「数値オブジェクト」として扱われます。

Rubyで整数のデータを表現するのは簡単です。そのまま数字を並べて書けばよいだけです。

1

と書けば「1」の値の整数(Fixnum)オブジェクトになります。また、

100

と書けば、「100」の整数オブジェクトになります。さらに、

3.1415

などと書けば、「3.1415」の値の浮動小数点数(Float)オブジェクトになります。

※「Fixnum」や「Float」というのは、それぞれのオブジェクトが所属する「クラス」の名前です。


数値を表示するには、文字列と同様にprintメソッドやputsメソッドを使います。

ふむふむ。なるほど。やってみましょう。

  • プログラム
puts 1
puts 100
puts 3.1415

puts 1.class
puts 100.class
puts 3.1415.class
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
1
100
3.1415
Fixnum
Fixnum
Float

なるほど、書いてある通りですね。



四則演算

数の計算を行ったり、その結果を表示したりすることもできます。四則演算をやってみましょう。

はーい。

  • プログラム
print "1 + 1 = ", 1 + 1, "\n"
print "2 - 3 = ", 2 - 3, "\n"
print "5 * 10 = ", 5 * 10, "\n"
print "100 / 4 = ", 100 / 4, "\n"
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
1 + 1 = 2
2 - 3 = -1
5 * 10 = 50
100 / 4 = 25

おおお。計算できました。

プログラミングの世界では、掛け算の記号に「*」を、割り算の記号に「/」を使うのが一般的です。Rubyもこの習慣にならっています。


ちょっと意地悪して、2つほど実験してみましょう。

四則演算の実験1

  • プログラム
print "10 / 3 = ", 10 / 3
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
10 / 3 = 3

ちょwwwwwテラうそつきwwwwwww
ゆとり教育の「円周率は3」的な匂いを感じます。


四則演算の実験2

  • プログラム
y = 0
for i in 1..100
y = 0.1+y
end

print y

上記は、0.1 を100回足すというプログラムです。単純に考えると、答えは10ですよね。

  • 実験結果
C:\enjoy_ruby>ruby helloruby.rb
9.99999999999998

ちょwwwwwwテラうそつきwwwwwww
コンピュータが壊れたのでしょうか?



では、謎を解いていきましょう。



四則演算の実験1の謎

10 / 3 = 3
うーん。普通は3.33333333・・・ とかになりますよね。
なぜ 3 なのか。


それは、
整数と浮動小数点数の演算結果 - 数値と四則演算 - Ruby入門
こちらに書いてあります。

演算を行う場合、整数と整数、浮動小数点数浮動小数点数だけではなくに整数と浮動小数点数に対して演算を行うことも可能です。ただし演算の結果得られる数値が整数になるか浮動小数点数になるかは注意が必要です。

左辺 右辺 演算結果
整数 整数 整数
整数 浮動小数点数 浮動小数点数
浮動小数点数 整数 浮動小数点数
浮動小数点数 浮動小数点数 浮動小数点数


つまり、整数と整数の演算だったので、出力も整数になるというものです。


ですので、どちらかを浮動小数点数でかけば、3.33333〜みたいな出力結果になるはずです。やってみましょう。

  • プログラム
print "10.0 / 3 = ", 10.0 / 3
  • 実行結果
C:\enjoy_ruby>ruby helloruby.rb
10.0 / 3 = 3.33333333333333

ktkr でたー!
しかし、なぜ 3.33333333333333 なのでしょうか。
3.33333333333333... みたいなエンドレスマークがついてもよい気もしますが・・・。


それは、
まつもと直伝 プログラミングのオキテ 第15回 浮動小数点数の謎に満ちた世界(2ページ目) | 日経 xTECH(クロステック)
こちらに書いてあります。

浮動小数点数は有限である
 数学上の数は無限のケタを持つことがありますが,浮動小数点数は有限の情報しか持てません。浮動小数点数は単精度(float)で32ビット,倍精度で64ビットしかありません。このビット数で表現できる数には限りがあるのです。


・・・あってるのかな?wwつっこみ歓迎ですwwww


四則演算の実験2の謎

0.1 を100回足すというプログラムです。単純に考えると、答えは10ですよね。
なぜ、Ruby(コンピュータ)は 9.99999999999998 と回答するのでしょうか。


それは、コンピュータが2進数を扱っていることに関連しています。

「10進数の小数点数の中には、2進数に変換できないものがある」からです。
たとえば、10進数の0.1は、決して2進数で表せません。小数点以下が100桁あっても表せないのです。

・・・(省略)・・・

実際、10進数の0.1を2進数に変換すると、0.000110011・・・(以下1100の繰り返し)という「循環小数」になります。これは、1/3を10進数で表せないのと同じことです。1/3は、0.3333・・・という循環小数になりますよね。

変数dに0.1を格納した時点で、2進数が近似値になってしまったのです。0.1の近似値を100回加えても、結果は10にはなりません。有限な機械であるコンピュータは、無限に続く循環小数を取り扱うことができません。変数のデータ型に応じたビット数に合わせて途中でカットしてしまいます。これによって、0.3333・・・という循環小数を途中でカットして0.333333とした場合に、それを3倍にしてもにはならない(0.999999となる)ことと同じ問題が発生するのです。

※「プログラムはなぜ動くのか」から抜粋

えーと、説明不足であったり、分かりにくいかもしれません・・・その場合は「プログラムはなぜ動くのか」を見てください。


http://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AF%E3%81%AA%E3%81%9C%E5%8B%95%E3%81%8F%E3%81%AE%E3%81%8B-%E2%80%95-%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E7%9F%A2%E6%B2%A2-%E4%B9%85%E9%9B%84/dp/4822281019




環境

C:\enjoy_ruby>ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]