とある事情があって、Ruby on Railsの勉強をすることになった。プロフィールにもあるとおり普段の仕事はPHP + PostgreSQLで行っているので、これはちょっとした事件だったりする。

状況はこんな感じ。

  1. Ruby on Railsの開発者が急遽必要になった
  2. 内部スタッフで対応しなければ
  3. 勉強会を開いて技術指導しよう
  4. 指導するにはまず私が習得しないと
  5. あわててはじめるRuby on Rails ← いまここ

まずはRails以前にRubyの基礎を身につけなければなるまい、ということで、このスライド[pdf]の要領で環境を構築し、基本的な言語構造を学習した。

なお、このエントリはCyxxxx Lightning Talks Vol.11において発表したもの、およびその(技術寄りの)補足である。

●環境構築

Windows上では「Instant Rails」を使うのが一番簡単に環境構築する方法のようだ。ダウンロードして解凍すればOKという手軽さは素晴らしい。Ruby以外にMySQL、apache、PHP4(とphpMyAdmin)まで含まれている。

]3

  • 注意事項
  • ブランクの入らないパスにインストールする
  • 例:C:\Apz\InstantRails-2.0-win

個人的にMeadowを使っているため、この中で作業ができるとありがたい。ruby-modeもあるしirb(Interactive Ruby)もMeadow上で動くので、迷わず導入していつもの環境でいろいろ試せるようにする。

●学習教材

もう4年も前(私がまだゲーム作ってたころ)の記事だが、いまだに有用なのでこの記事を学習の入り口として推薦する。「他言語プログラマ向けRuby入門記事」というコンセプトはうってつけ。

参考書は「初めてのRuby」がお勧め。こちらも同じく「他言語プログラマ向けRuby入門書」。


●動かしてみた感想

PHPとの違いを中心に。

  • ちゃんと「型」がある

    stringの“1”にintegerの2を足すとエラーが出る。

  • ハッシュが順番を保持しない

    これは不便じゃないか?

  • 0も"0"もtrue

    これは間違えそうなので要注意。

  • ++ / –が存在しない

    あってもよさそうだけど。ダメですか。

  • メソッドをオーバーロードできない

    オーバーライドはできる(これはPHPと同じか)。

    引数の数 / 型で処理を分けたいときは自前で分岐させる。

●コード(学習メモ)を例示していろいろ

  • 型についてのいろいろ
# 文字列に数値を足してみる
irb(main):003:0> b = "piyo" ; puts b + 3
TypeError: can't convert Fixnum into String     # 型でエラーが出た!
    from (irb):3:in `+'
    from (irb):3
    from :0
irb(main):007:0> c = "15" ; puts b + 3
TypeError: can't convert Fixnum into String     # 当然ながら"15"に3は足せない
    from (irb):7:in `+'
    from (irb):7
// PHPは$bを数値として評価しようとして0を返す。
$ php -r "$b = 'piyo' ; echo $b + 3 ; "
3

// PHPは$cを数値として評価しようとして(そして成功して)15を返す。
$ php -r "$c = '15' ; echo $c + 3 ; "
18
  • hashにおいてはキーの型も重要
irb(main):030:0> h2 = {1 =>"hoge", "2" => "piyo", "foo" => "bar"}
{1=>"hoge", "foo"=>"bar", "2"=>"piyo"}
# key =  1
irb(main):032:0> h2[1]
"hoge"
irb(main):033:0> h2["1"]
nil                                             # "1"は1と違う
# key = "2"
irb(main):034:0> h2[2]
nil                                             # 2は"2"と違う
irb(main):035:0> h2["2"]
"piyo"
// PHPでも試してみる
$ php -r "$h2 = array(1 =>'hoge', '2' => 'piyo', 'foo' => 'bar') ; \
          var_dump($h2[1]) ; \
          var_dump($h2['1']) ; "
string(4) "hoge"
string(4) "hoge"
  • 0と"0"はtrue
# test0.rb
h3 = {
  "integer_0" => ,
  "string_0" => "0",
  "boolean_false" => false,
  "nil" => nil
}

h3.each { |key,value|
  print key + " : "
  if value
    puts "true"
  else
    puts "false"
  end
}
$ ruby test0.rb
string_0 : true
integer_0 : true
boolean_false : false
nil : false
  • 0と"0"はtrue
  • 0と"0"はtrue
  • 0と"0"はtrue

大事なので3回繰り返した。

<?php
// test0.php
$h3 = array("integer_0" => ,
            "string_0" => "0",
            "boolean_false" => false,
            "nil" => null) ;
foreach ($h3 as $key => $value)
{
    print("{$key} : ") ;
    if ($value) print("true\n") ;
    else        print("false\n") ;
}
?>
$ php test0.php
integer_0 : false
string_0 : false
boolean_false : false
nil : false
  • 文字列はmutable
# test1.rb
# << と + の違い
a = "foo"
b = "bar"
c = "hoge"
d = "piyo"

p a + b                         # aとbを連結した新しい文字列が返る
p a
p b

p c << d                        # cにdを破壊的に連結する
p c
p d
$ ruby test1.rb
"foobar"                        # aとは別のインスタンス
"foo"
"bar"
"hogepiyo"
"hogepiyo"                      # 破壊されたc
"piyo"
  • クラスいろいろ
# クラス定義
class Hoge
  def initialize(x)             # コンストラクタ
    @@static_var = 10           # クラス変数
    @private_var = x            # インスタンス変数
    puts "constructed with " + @private_var.to_s
  end

  def print                     # クラスメソッド
    p @private_var
    p @@static_var
  end

  # attributeでアクセサを定義できる
  attr_reader   :private_var    # 読み出し
  attr_writer   :private_var    # 書き込み
  attr_accessor :private_var    # 読み書き
end

# サブクラス
class Piyo < Hoge
  def set_static_var(x)
    @@static_var = x
    p @@static_var
  end
end

# さっきのクラスの定義をしれっと再開できる
class Hoge

  # クラス変数へのアクセサを作ってみる
  def view_static_var
    p @@static_var
  end
  def set_static_var(x)
    @@static_var = x
  end

  # 自分のメソッドを自分でオーバーライド
  def print
    puts "over-rided method."
  end
end

●その他