2006-01-01から1ヶ月間の記事一覧

Duck typing

Duck typingというのは、本当の型はクラスではなくオブジェクトが知っているという話。(if it walks like a duck, and talks like a duck, then it might as well be a duck) 参考: Duck typing - Wikipedia 参考: DuckTyping - rubygarden.org

String#each

String#eachメソッドは、普通は行単位で区切ります。 s = <<"EOD" This is the 1st line. This is the 2nd line. This is the 3rd line. EOD s.each { |line| p line }実行結果です。 "This is the 1st line.\n" "This is the 2nd line.\n" "This is the 3rd…

String#dump

String#dumpメソッドは文字をエスケープしてくれます。irbを使ってdumpとevalに戯れてみました。 irb(main):001:0> s = "print \"Ruby!\"\n" => "print \"Ruby!\"\n" irb(main):002:0> eval s Ruby!=> nil irb(main):003:0> p s "print \"Ruby!\"\n" => nil …

forwardableとdelegate

面白そうなので、後で読むことにします。 委譲 (forwardableとdelegate)

るびま

こちらも、あとで読むことにします。気が付くとrubyco(るびこ)と一字違いですね。 るびま

変数$!はスレッドローカル

変数$!がスレッドローカルであることを確認してみます。 begin raise "Outer" rescue print "#{Thread.current} #{$!}\n" Thread.start { begin raise "Inner" rescue print "#{Thread.current} #{$!}\n" end }.join print "#{Thread.current} #{$!}\n" end…

環境変数ENV

環境変数は標準オブジェクトENVを使うと参照・変更できます。 for k in ENV.keys.sort print k, "=>", ENV[k], "\n" end

特異メソッド

無理やりに作った特異メソッドの例です。 def nil.rubyco print "Hello!\n" end a = nil a.rubyco # "Hello!" nil.rubyco # "Hello!"Rubycoのクラスメソッドrubycoを書くときにdef Rubyco.rubyco ... endではなくdef self.rubyco ... endと書けるのは、クラ…

配列引数

Rubyでは、*引数で配列引数が作れます。デフォルト値は指定できません。 def rubyco(x, y, *rest) p rest end # rubyco() # wrong number of arguments (0 for 2) (ArgumentError) # rubyco(1) # wrong number of arguments (1 for 2) (ArgumentError) rubyc…

バブルソート

Arrayのインスタンスメソッドとしてbubble_sortを実装してみました。範囲の指定は1...self.lengthがいちばんしっくりきました。 class Array def bubble_sort loop { sorted = true for i in 1...self.length if self[i-1] > self[i] self[i-1], self[i] = s…

シンボルと%s

%s記法でシンボルを書けます。 p :Rubyco.equal?(%s|Rubyco|) # => true

Proc

Proc.newは、コンテキスト+ブロックをオブジェクト化します。以下のrubycoメソッドは、ローカル変数nのコンテキストを包んだProcオブジェクトを返します。Proc#callメソッドを呼ぶたびにProcオブジェクトが実行され、増えた値を表示します。 def rubyco n =…

Procではreturn不可

Procではreturnできません。 adder = Proc.new { |x, y| # return x + y # unexpected return (LocalJumpError) x + y } p adder.call(1, 2) # => 3

未定義の変数

Rubyでは、未定義のグローバル変数はnilですが、未定義の局所変数に参照するとエラーになります。 p $a p b実行結果はこうなります。 nil undefined local variable or method `b' for main:Object (NameError)

変数は型なし

Rubyでは、変数に型はありません。つまり、ある変数に異なる型のオブジェクトを代入することができます。 x = "hello" p x.class x = %r/hello/ p x.class x = [ "hello" ] p x.class実行結果はこうなります。 String Regexp Array

定数の中身の変更

名前を大文字で始めると定数になります。定数に再代入すると警告がでますが、定数として参照しているオブジェクトの中身を変更しても警告はでません。 A = [ 1, 2, 3 ] p A[0] # => 1 A[0] = 100 p A[0] # => 100

メソッドと定数

Rubyでは、メソッド内で定数を定義することはできません。dynamic constant assignmentというエラーになります。 def rubyco A = 100 end

@@でクラス変数

Rubyでは、@@で名前を始めるとクラス変数になります。 class Rubyco @@x = 0 def self.inc @@x += 1 end def self.dec @@x -= 1 end def self.value @@x end end p Rubyco.value # => 0 Rubyco.inc p Rubyco.value # => 1 Rubyco.dec p Rubyco.value # => 0

ブロックパラメータは外部から継承

Rubyでは、ブロックパラメータと同じ名前の変数が前にあったらそれを使います。ブロックパラメータは新しいスコープを作るわけではないのでしょうか。これはちょっと驚きです。 a = [ 1, 2, 3 ] rubyco = 100 p rubyco # => 100 a.each { |rubyco| # ... } p…

irb: インタラクティブなRuby

irbを使うと、インタラクティブにRubyを使うことができます。以下では「じゃ、そのクラスは何よ?」としつこく尋ねてみました。 irb(main):001:0> nil => nil irb(main):002:0> nil.class => NilClass irb(main):003:0> nil.class.class => Class irb(main):…

sizeとlength

Rubyでは、Array#sizeとArray#lengthは同じ意味です。

defined?

変数が定義されているかどうかは、defined?演算子で調べられます。defined?はメソッドではありません。 if defined?(x) print "x is defined.\n" else print "x is not defined.\n" # こちら end x = nil if defined?(x) print "x is defined.\n" # こちら e…

File.exist?

ファイルの有無は、File.exist?で調べます。File.exists?はobsoleteのようです。

Time.now.to_i

現在の秒を整数で欲しいときにはto_iをつけましょう。 p Time.now # => Wed Jan 25 15:53:30 東京 (標準時) 2006 p Time.now.to_i # => 1138172006

インデント付きヒアドキュメント

Rubyでは、 print <<"EOD" Hello, hello, hello. Hello, hello, hello. Hello, hello, hello. EOD print <<-"EOD" Hello, hello, hello. Hello, hello, hello. Hello, hello, hello. EOD

idとobject_id

Rubyで、"string".idを使おうとしたら、warning: Object#id will be deprecated; use Object#object_idという警告が出ましたのでobject_idを使います。 文字列リテラルは、コード中に出てくると新たにnewするようです。object_idが異なるのでわかります。 if…

intern

Rubyでは、:をつけるとシンボルが得られます。同じシンボルは同じオブジェクトです。 print :Rubyco, "\n" # => Rubyco if :Rubyco == :Rubyco print "1 Same\n" # => 1 Same end if :Rubyco.object_id == :Rubyco.object_id print "2 Same\n" # => 2 Same e…

代入の有無とメソッド呼び出し

Rubyでは、変数とメソッドの区別が付かないとき、以前に代入があるかどうかを調べて判断します。 def f "function\n" end print f # => function f = "var\n" print f # => var print f() # => function

timesメソッド

timesメソッドによる繰り返しです。 10.times {|i| print "i = #{i}\n" }

ri -c

ri -cで、riが知っているクラスとモジュールの一覧が表示されます。