2010-01-25 Ruby基礎文法最速マスター
■ Perl基礎文法最速マスターをだいたいそのまま、Rubyに置き換えてみました。
他の言語をある程度知っている人はこれを読めばRubyの基礎をマスターしてRubyを書くことができるようになる…かも知れません。無保証です。
参考:
■ 1. 基礎
インタラクティブRuby (irb)
irbを使うと、Rubyのプログラムを簡単に練習することができます。
/Users/yhara $ irb irb(main):001:0> puts "hello" hello => nil irb(main):002:0> 1 + 1 => 2
以下の説明は、irbを起動して、自分で試しながら読むと習得が早いと思います。
表示 (print, puts, p)
print "foo" #=> 改行なし puts "foo" #=> 改行あり p 123 #=> デバッグ用
いわゆる「printfデバッグ」は、Rubyでは「pデバッグ」になります。
変数の宣言
Rubyには変数宣言はありません。また変数の型もないので、一つの変数にいろいろなクラスのオブジェクトを代入することができます。
a = 123 a = "abc" #=> aを上書きする
Rubyでは先頭の一文字によって変数の種類が変わります。
foo #=> ローカル変数 @foo #=> インスタンス変数(@) @@foo #=> クラス変数(@@) $foo #=> グローバル変数($) FOO #=> 定数(大文字から始まる)
コメント
「#」以降はコメントになります。
# コメント
スクリプトの実行
$ ruby foo.rb
出力結果をファイルに書き出すにはリダイレクトを使います。
$ ruby foo.rb > out.txt
■ 2. 数値
num = 1 num = 1.234 num = 100_000_000
四則演算
num = 1 + 1 num = 1 - 1 num = 1 * 2 num = 5 / 2 #=> 2 (整数どうしの割り算は整数になる) num = 5.0 / 2 #=> 2.5 (どちらかが小数なら結果も小数) num = 5 % 2 #=> 1 (余りをとる)
インクリメントとデクリメント
Rubyには++演算子がないので、+=や-=を使います。
i += 1 i -= 1
■ 3. 文字列
文字列はシングルクォートかダブルクォートで囲みます。ダブルクォートの中では\t(タブ)や\n(改行)などの特殊文字を利用することができます。またダブルクォートで囲まれた文字列の中では「#{}」を使って任意の式を展開することができます。
str1 = 'abc' str2 = "def" str3 = "a\tbc\n" str4 = "#{str1} def" #=> "abc def"
文字列操作
結合
str1 = "aaa" + "bbb" str2 = ["aaa", "bbb", "ccc"].join(",")
分割
record = "aaa,bbb,ccc".split(/,/)
長さ(文字数)
length = "abcdef".length length = "abcdef".size # String#sizeとString#lengthは同じ動作。好きな方をどうぞ
切り出し
substr = "abcd"[0, 2] #=> "ab" (0番目から2文字)
検索
idx = "abcd".index(/bc/) #=> 1
■ 4. 配列
配列は「[]」を使います。
ary = [100, 200, 300]
要素の参照と代入
a = ary[0] #=> 100 b = ary[1] #=> 200
ary[0] = 1 ary[1] = 2
要素の個数
n = ary.length n = ary.size # Array#sizeとArray#lengthは同じ動作。好きな方をどうぞ
配列の操作
ary = [1, 2, 3] # 先頭を取り出す a = ary.shift #=> aは1、aryは[2,3]に # 先頭に追加 ary.unshift(5) #=> aryは[5,2,3]に # 末尾を取り出す b = ary.pop #=> bは3、aryは[5,2]に # 末尾に追加 ary.push(9) #=> aryは[5,2,9]に
■ 5. ハッシュ
ハッシュ(辞書)は「{}」を使います。
hash = {"a" => 1, "b" => 2}
キーには文字列よりも、シンボル(英語しか使えないが軽い文字列みたいなもの)を使うことが多いですが。
hash = {:a => 1, :b => 2}
要素の参照と代入
hash["a"] #=> 1 hash["b"] #=> 2
hash["c"] = 5 hash["d"] = 7
ハッシュの操作
キーの取得
hash.keys #=> ["a", "b", "c", "d"] (Ruby 1.8.xでは順不動)
値の取得
hash.values #=> [1, 2, 5, 7] (同上)
キーの存在確認
hash.key?("a") #=> true
ハッシュのペアの削除
hash.delete("a")
■ 6. 制御文
Rubyでは、条件文で偽と見なされるのはfalseとnilのみで、それ以外のオブジェクトは 全て真と見なされます(0や空文字列も真)。
if文
if a == 1 ... elsif b == 2 ... else ... end
while文 (あまり使いませんが)
i = 0 while i < 5 ... i += 1 end
Array#eachとブロックを使った繰り返し
[1, 2, 3].each do |i| # 「do |..| .. end」のことをブロックと呼びます puts i # Array#eachは、各要素をブロックに渡して実行してくれます end # 1, 2, 3と順に表示します。 [1, 2, 3].each{|i| # ブロックには「{|..| .. }」というちょっと短い記法もあります。 puts i # 上の記法とは(結合順位が違うだけで)全く同じ動作になります。 }
Integer#timesとブロックを使った繰り返し
5.times do |i| # 0, 1, 2, 3, 4と順に表示します puts i end 5.times do # 値を使わないときは、「|..|」の部分は書かなくて構いません puts "hello" end
Kernel#loopとブロックを使った無限ループ
loop do puts "stop me!" # 無限に表示し続けるので、Ctrl-Cで止めてください。 end
その他の繰り返し
Enumerableモジュールには、繰り返しを行う便利なメソッドがたくさん定義されています。
条件に合うものだけを選ぶ
[1,2,3,4,5].select{|x| x.even?} #=> [2,4]
条件に合うものを除く
[1,2,3,4,5].reject{|x| x.even?} #=> [1,3,5]
条件に合う最初のものを返す
[1,2,3,4,5].detect{|x| x.even?} #=> 2
等しい値があるか調べる
[1,2,3,4,5].member?(3) #=> true
条件に合うものがあるか調べる
[1,2,3,4,5].any?{|x| x.even?} #=> true
全ての要素が条件に合うかを調べる
[1,2,3,4,5].all?{|x| x.even?} #=> false
条件に合うものの個数を数える
[1,2,3,4,5].count{|x| x.even?} #=> 2
最大のものを返す
[1,2,3,4,5].max #=> 5
最小のものを返す
[1,2,3,4,5].min #=> 1
加工結果が最大のものを返す
[1,-2,3,4,-5].max_by{|x| x.abs} #=> -5
加工結果が最小のものを返す
[1,-2,3,4,-5].min_by{|x| x.abs} #=> 1
昇順にソートする
[1,-2,3,4,-5].sort #=> [-5, -2, 1, 3, 4]
加工結果で昇順にソートする
[1,-2,3,4,-5].sort_by{|x| x.abs} #=> [1, -2, 3, 4, -5]
加工結果を配列で返す
[1,-2,3,4,-5].collect{|x| x.abs} #=> [1, 2, 3, 4, 5]
selectにはfind_all、rejectにはdelete_if、detectにはfind、member?にはinclude?、collectにはmapという別名があります。 *1
*1 Rubyistはcollect派とmap派に二分されますが、筆者はmap派です。理由はタイプ数が少ないからです
■ 7. サブルーチン
Rubyには「サブルーチン」というものはありませんが、 トップレベルでメソッド定義を行うことで、どこからでも呼べるメソッドを定義することができます。 これはサブルーチンのように使うことができます。
def sum(x, y) return x + y end p sum(1,2) #=> 3
■ 8. ファイル入出力
読み込み
とりあえずFile.readだけ覚えておけばなんとかなると思います。
str = File.read("foo.txt") #=> strに、foo.txtの内容を丸ごと含む文字列が代入される
書き込み
File.openで開いて、IO#writeで書き込みます (IO#putsとかもあります)。
File.open("out.txt", "wb") do |f| f.write str end
■ 知っておいた方がよい文法
Rubyの真偽値
前述のように、falseとnilが偽、それ以外の全ての値は真です。
「nil」は値がないことを示す特別な値です。例えば、配列で範囲外の要素を取ろうとするとnilが返ってきます。
ary = [1,2,3] ary[100] #=> nil
コマンドライン引数
ARGVという組み込み定数に入っています。
# ruby foo.rb a.txt b.txt としたとき: p ARGV #=> [a.txt, b.txt]
C言語と違って、ARGV[0]にプログラム名が入っていたりはしません。プログラム名は$0という変数から取得できます。
# ruby foo.rb a.txt b.txt としたとき: p $0 #=> foo.rb
unless式
ifの逆です。
unless a == 1 do ... end
後置のif (if修飾子)
Rubyではifやunlessを文の後ろに置くことができます。
puts "ok" if x == 1 puts "ng" unless x == 1
クラス定義
クラスは「class..end」で定義します。
class Person def initialize(name, age) @name, @age = name, age @address = nil end attr_reader :name, :age attr_accessor :address end jhon = Person.new("Jhon", 15) p jhon.name jhon.address = "USA, Earth"
その他のよく使うクラス
■ 余談
本体に入らなかった、Rubyの「仕組み」についての話です。
全てがオブジェクト
Rubyでは、全ての値が、いずれかのクラスに属するオブジェクトです。 例えば数値の「1」はFixnumクラス、文字列「"foo"」はStringクラス、 配列「[1,2,3]」はArrayクラスのオブジェクトです。
全てがメソッド
Rubyには「関数」のようなものはなく、printやputsでさえもKernelモジュールに定義されたメソッドです。
puts "foo" # これは、 self.puts "foo" # これの省略形 p self #=> main (トップレベルのselfは、mainという特別なオブジェクト) p self.class #=> Object (mainは、Objectクラスのインスタンス) # (Objectクラスは、Kernelモジュールをインクルードしている) # (なので、トップレベルでputsと書ける)
Kernelモジュールに定義されたメソッドは、プログラムのどこからでも呼び出せます。
Rubyでは演算子もメソッドです。例えば「1 + 2」はInteger#+の呼び出し、 「ary[1]」はArray#[]の呼び出し、「ary[1] = 2」はArray#[]=の呼び出しです。
■ (おまけ)Ruby書籍紹介
筆者の独断と偏見によるRuby書籍紹介です。
- 他のプログラミング言語をマスターしていて↓
- プログラミングとかあんまり慣れてない↓
- これ一冊でOK、的な本がほしい
- 4797336617
- 何かを作りながら学びたい
- 4777512924 4797352604
- これ一冊でOK、的な本がほしい
- コンピュータにあまり慣れてない↓
- 初歩から応用まで一冊で
- 4798019437
- 基礎から応用までじっくりと
- 4798117994 4798118001 479811801X
- 堅苦しいのはいやなの
- 4844327704
- 初歩から応用まで一冊で
- 基礎は分かったんで↓
- どんなことができるのか知りたい
- 4863540221 4797340045
- なんか作ってみたい
- 4839927847 4839932115 483993178X 4839931496
- Webアプリがやりたい
- 4274067858 4873114381
- 「まつもとゆきひろ」を「ひろゆき」と間違えないようになりたい
- 4822234312
- どんなことができるのか知りたい
変数の宣言のところにスコープについて補足するともっとよくなると思います。<br><br>ifやbeginはスコープを導入しないから<br><br>if a >= 0<br> x = a<br>else<br> x = -a<br>end<br>p x<br><br>begin<br> result = something.try<br>rescue<br> #...<br>end<br>p result<br><br>とできるけど、ブロックは導入するので<br><br>list.each do |x|<br> if x > 0<br> flag = true<br> end<br>end<br>p flag<br><br>はだめ、みたいなことです。<br><br>(whileとかforはスコープを導入しないってのは教育的配慮で教えない方がいいのかもしれない)
四則演算の最後の余りは1になりますかね。
Enumertableのminの部分がmaxになってるような・・
ひろゆきワロタ
classのところで書き忘れ?<br><br>jhon = Person.new("Jhon", 15)<br>p jhon.name #=>"Jhon"<br>p jhon.age #=>15<br>jhon.address = "USA, Earth"<br>p jhon.address #=>"USA, Earth"