ruby学習メモ
Shift_JIS を指定したい場合
$KCODE='SJIS'
その他 "EUC" "SJIS" "UTF8" "NONE" が指定可能、デフォルトは"NONE"
"NONE"はマルチバイト文字列を認識なし。
d:id:gaba:20060702:p6
http://www.ruby-lang.org/ja/man/?cmd=view;name=%C1%C8%A4%DF%B9%FE%A4%DF%CA%D1%BF%F4#a.24KCODE
ruby学習メモ
- モジュールの優先順位
# モジュール1の定義 module Sample1 def test puts "Sample1!!" end end # モジュール2の定義 module Sample2 def test puts "Sample2!!" end end
class Clazz1 include Sample1 include Sample2 end Clazz1.new.test => Sample2!! # 最後に宣言した Sample2#test が呼び出される class Clazz2 include Sample2 include Sample1 end Clazz2.new.test => Sample1!! # 最後に宣言した Sample1#test が呼び出される class Clazz3 def test puts "Clazz3!!" end include Sample2 include Sample1 end Clazz3.new.test => Clazz3!! # クラス Clazz3 に定義された test が呼び出される
# スーパークラスの定義 class SuperClazz def test puts "superClazz!!" end end
class Clazz4 < SuperClazz end Clazz4.new.test => superClazz!! # スーパークラスに定義された test が呼び出される class Clazz5 < SuperClazz def test puts "Clazz5!!" end end Clazz5.new.test => Clazz5!! # クラス Clazz5 に定義された test が呼び出される class Clazz6 < SuperClazz include Sample1 end Clazz6.new.test => Sample1!! # Sample1#test が呼び出される
ruby学習メモ
- while
file = File.open("Ex084.txt") while line = file.gets print if line =~ /start/ .. line=~ /end/ end
Ex084.txt の内容
1 start 3 4 end 6
出力結果
start 3 4 end
$. で読み込んだ行を表示することが出来る puts $. print "行数:#{$.}"
- begin/end を使用する際の注意
# 実行されない print "Hello\n" while false # 1回実行される begin print "Goodby\n" end while false
実行結果
Goodby
begin/end の場合は必ず1回実行される。
イテレータによる繰り返し
puts "test1" 0.upto(9) do |x| print x, " " end print "\n\n" puts "test2" 0.step(16, 5) {|x| print x, " "} print "\n\n" puts "test3" [ 1, 1, 2, 3, 4 ].each {|x| print x, " "}
結果
test1 0 1 2 3 4 5 6 7 8 9 test2 0 5 10 15 test3 1 1 2 3 4
- for in
print "\n\n" for v in [1,2,3,4,5] print v, " " end
1 2 3 4 5
- クラスに each メソッドを宣言すると、for in で使用することが出来る
class EachableClass def each yield "value1" yield "value2" yield "value3" end end for v in EachableClass.new print v, " " end
value1 value2 value3
break redo next
break | もっとも内側のループを抜ける。 |
next | ループの終わりにジャンプし、次の繰り返しに入る。continue 見たいな |
redo | 次の要素に移動せず、もう一度ブロックの処理を行う。 |
retry | ループを最初から起動しなおす。 |
break に引数を指定することが出来る
result = for v in [1,2,3,4,5] break(v * 10) if v == 3 end print result => 30
引数が省略されている場合は nil を引き渡したものとします。
変数のスコープ・ループ・ブロック
while | スコープは生成されない |
until | スコープは作成されない |
for in | スコープは作成されない。for xxx in の xxx もスコープが作成されないので注意 |
eachなどのブロック | ブロック内で定義された値はローカルスコープとなる。ただしブロック外で既に定義されている変数についてはその変数が使用されるため、スコープも継承される |
ruby学習メモ
条件式
nil でも 定数 false でもないものは全て真(true)を意味する
演算子 | 意味 |
== | 等価性をテストする |
=== | case 文の when で使用 |
<=> | 汎用比較演算子。レシーバが引数より小さいとき -1, 両者が等しいとき 0, レシーバが引数より大きいとき +1 を返す |
<, <=, =>, > | 大小の比較 |
=~ | 正規表現パターンマッチ |
eql? | レシーバと引数の型と値が等しいとき true を返す。例えば、1 == 1.0 は true、1.eql?(1.0) は false |
equal? | レシーバと引数のオブジェクトIDが同じとき true を返す |
論理式の値
words = Hash.new (words[:key] ||= []) << "value1" => ["value1"] (words[:key] ||= []) << "value2" => ["value1", "value2"] #上記は以下と同じ words[:key] = words[:key] || [] words[:key] << "value3" => ["value1", "value2", "value3"]
条件式
- if文
if 〜 then [exp] elsif 〜 then [exp] else [exp] end
- if 文を複数行にまたがって書くときは then を省略できます。
if 〜 [exp] elsif 〜 [exp] else [exp] end
- then の代わりに : を使用する
if 〜: [exp] elsif 〜: [exp] else [exp] end
- unless(if文の否定)
unless 〜 [exp] else [exp] end
- if修飾子
puts "aaa" if true => aaa と表示される puts "aaa" if nil => aaa と表示されない -case式 >|ruby| #うるう年 def leep(year) leep = case when year % 400 == 0: true when year % 100 == 0: false else year % 4 == 0 end return leep; end leep(2000) => true leep(2100) => false
def test while line = gets case line.chomp! when "debug" puts "debug!!" when "quit" return else puts line end end end # then キーワードも使用可能 case line.chomp! when "debug" then puts "debug!!" when "quit" then return else puts line end # コロンも使用可能 case line.chomp! when "debug": puts "debug!!" when "quit": return else puts line end
ruby学習メモ
コマンド展開
OSによりコマンドとしいて実行される。末尾に改行が付く
`echo aaa` => "aaa\n"
%x{ echo "aaa" } => "\"aaa\"\n"
def duration=(new_duration) puts "new duration = #{new_duration}" @duration = new_duration end end song = Song.new;song.duration = "hogehoge"
代入の返却値は破棄される。
class RetTest def hoge=(new_value) @value = new_value return 100 end end
下記の場合は value に 100 ではなく 20 が設定される
test = RetTest.new value = test.hoge = 20 value => 20
属性書き込みメソッドの場合はself が暗黙レシーバにならない
class BrokenAmplifier attr_accessor :left_channel, :right_channel def volume=(vol) left_channel = self.right_channel = vol end end
ba = BrokenAmplifier.new ba.left_channel = ba.right_channel = 99 ba.volume = 5 ba.left_channel => 99 ← 5 にならない ba.right_channel => 5
多重代入
代入される値が代入に影響を与えない
value = 1 value, value = 100,value => [100, 1] ← [100,100]にはならない value => 1
a = [1,2,3,4] b, c = a => [1, 2, 3, 4] b => 1 c => 2 b, *c = a => [1, 2, 3, 4] b => 1 c => [2, 3, 4] b, c = 99, a => [99, [1, 2, 3, 4]] b => 99 c => [1, 2, 3, 4] b, *c = 99, a => [99, [1, 2, 3, 4]] b => 99 c => [[1, 2, 3, 4]] b, c = 99, *a => [99, 1, 2, 3, 4] b => 99 c => 1 b, *c = 99, *a => [99, 1, 2, 3, 4] b => 99 c => [1, 2, 3, 4]
b,(c,d),e=1,2,3,4 => [1, 2, 3, 4] b => 1 c =>2 d=>nil e=>3 b,(c,d),e=[1,2,3,4] => [1, 2, 3, 4] b => 1 c=>2 d=>nil e=>3 b,(c,d),e=1,[2,3],4 => [1, [2, 3], 4] b=>1 c=>2 d=>3 e=>4 b,(c,d),e=1,[2,3,4],5 => [1, [2, 3, 4], 5] b=>1 c=>2 d=>3 e=>5 b,(c,*d),e=1,[2,3,4],5 => [1, [2, 3, 4], 5] b=>1 c=>2 d=>[3, 4] e=>5
ruby学習メモ
配列展開メソッド呼び出し
アスタリスクをつけることにより、配列を展開してそれぞれを引数とすることが出来る
def five(a,b,c,d,e) "#{a} #{b} #{c} #{d} #{e}" end
five(1,2,3,4,5) => "1 2 3 4 5"
five(1,2,3, *['4','5']) => "1 2 3 4 5"
five(*(1..5).to_a) => "1 2 3 4 5"
lambda
anyfunc = lambda {|n| n * n} ((1..10).collect(&anyfunc).join(", ")) => "1, 4, 9, 16, 25, 36, 49, 64, 81, 100"
lambda
与えられたブロックから手続きオブジェクト (Proc のインスタンス) を生成して返します(Proc.newと同じです)。
ブロックが指定されなければ、呼び出し元のメソッドで指定されたブロックを手続きオブジェクトとして返します。呼び出し元のメソッドがブロックなしで呼ばれると ArgumentError 例外が発生します。
def hashparam(name, params) "#{name} params=#{params}" end hashparam( "test", { :param1=>"value1", :param2=>"value2" }) => "test params=param1value1param2value2"
ruby学習メモ 練習問題
CodeZine「脱 超初心者 Javaアルゴリズム問題集 第2回」を ruby でやってみる
http://codezine.jp/careerup/article/aid/1495.aspx
問題1
標準入力された月、日が、今日であるかどうかを判定するプログラムを作成してください。
- コマンドラインに「今日は何月何日でしょう?」のメッセージを表示する。
- それぞれ、「何月?==> 」「何日? ==> 」を表示して入力を受け取る。
- 入力された月日が今日であれば「正解!!」、間違っていれば「間違っています」と表示する。
回答?
# 脱 超初心者 Javaアルゴリズム問題集 第2回 # 条件分岐(複合条件) # # http://codezine.jp/careerup/article/aid/1495.aspx class Study2 def start puts "今日は何月何日でしょう?" print "何月?==>" month = Integer(readline) print "何日?==>" day = Integer(readline) now = Time.now if month == now.month && day == now.day puts "正解!!" else puts "間違っています。" end end end Study2.new.start
メモ
month = readline.chomp!
だと
month == now.month
が true にならない。String と Fixnum で型が異なるため
irb(main):276:0> readline.chomp! => String irb(main):277:0> now.month.class => Fixnum