カテゴリ別 2003年 | 2004年 | 2005年 | 2006年 | 2007年 | 2008年
知り合いサイト: よんだもの / 暴想 / Linuxでやる夫 / 新宿Vipper / 僕だけが幸せになればいいのに。
preview が増えた分当初の予定より多少遅れたものの、無事 Ruby 1.8.7 がリリースされました。MUSHA さんお疲れさまです。いまのメンテナ体制なら 1.8 系は安泰ですね。
1.8.7 は 1.9 への架け橋となるようなバージョンです。1.9 から(互換性を損なわない範囲で)多くのメソッドがバックポートされました。また、1.9 でのメソッド追加や仕様変更に合わせて、前方互換性を確保するためのメソッド追加もされています。
今回、1.9 の機能のバックポート要望やバグ報告などはRubyForge の BTSが使われました。yugui さんが作業されていた Ruby 開発向け redmine 改が最近稼動し始めましたので、次のバージョンはそっちが使われるんじゃないかと思います。
1.8.7 で新しく増えたメソッドを使ったり 1.8.7 で変更された仕様に従ったコードは、もちろん 1.8.6 以下では動きません。1.8.6 以下の環境でも動く必要があるコードを書く際には使うのを避けるのが無難です。自分で好きに使える環境や 1.8.7 以上を前提にできる環境なら、新機能を駆使して書くとよりすっきりしたコードにできるんじゃないかと思います。
http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7/NEWS にコード例やマニュアルへのリンクを追加しつつ適当に訳してみました。
1.8.7 で使えるようになった 1.9 のメソッドについては、Ruby 1.8.7で使えるようになったRuby 1.9のメソッドたち - ’(rubikitch wanna be (a . lisper))を読んだ方が手っ取り早く把握できると思います。
== 1.8.6 リリースからの変更
=== ライブラリへの変更(主要なもののみ)
* 新ライブラリ
* securerandom
安全な乱数発生器のためのインターフェースを提供するモジュールです。
詳細は、http://doc.loveruby.net/refm/api/view/class/SecureRandom
を参照ください。
1.8.7 の cgi/session で利用されています。
* 組み込みライブラリ
* Array#flatten
* Array#flatten!
オプション引数 lv を指定した場合、指定の深さまで再帰的に平滑化できるように
なりました。
詳細は、http://doc.loveruby.net/refm/api/view/method/Array/i/flatten
を参照ください。
例
a = [ 1, 2, [3, [4, 5] ] ]
p a.flatten(1) #=> [1, 2, 3, [4, 5]]
1.8.7 用コードの 1.8.6 での挙動
a = [ 1, 2, [3, [4, 5] ] ]
p a.flatten(1)
#=> in `flatten': wrong number of arguments (1 for 0) (ArgumentError)
ArgumentError 例外が発生します。
* Array#eql?
* Array#hash
* Array#==
* Array#<=>
配列内のデータを再帰的に見るようになりました。
例
a = [{1 => 2}]
b = [{1 => 2}]
p a.hash #=> 831
p b.hash #=> 831
p a.eql?(b) #=> true
1.8.6 での挙動
a = [{1 => 2}]
b = [{1 => 2}]
p a.hash #=> -605776646
p b.hash #=> -605776666
p a.eql?(b) #=> false
* Array#index
* Array#rindex
ブロックをとることができるようになりました。
詳細は、http://www.ruby-lang.org/ja/man/html/Array.html#index を参照ください。
例
p [0, 1, 0, 1, 0].index {|v| v > 0} #=> 1
1.8.7 用コードの 1.8.6 での挙動
p [0, 1, 0, 1, 0].index {|v| v > 0}
#=> in `index': wrong number of arguments (0 for 1) (ArgumentError)
ArgumentError 例外が発生します。
* Array#collect
* Array#map
* Array#collect!
* Array#map!
* Array#each
* Array#each_index
* Array#reverse_each
* Array#reject
* Array#reject!
* Array#delete_if
ブロックを与えたなかった場合には Enumerator を返すようになりました。
ただし、互換性のため map と collect は 1.8.6 以前と同様に配列を返します。
なお、delete_if は 1.8.7 でも 1.9 でも配列を返します。(→ delete_if も Enumerator を返すようになりました)
例
p [1, 2, 3, 4, 5].collect #=> [1, 2, 3, 4, 5]
p [1, 2, 3, 4, 5].map #=> [1, 2, 3, 4, 5]
p [1, 2, 3, 4, 5].collect! #=> #<Enumerable::Enumerator:0xb7cc40b8>
p [1, 2, 3, 4, 5].map! #=> #<Enumerable::Enumerator:0xb7cc407c>
p [1, 2, 3, 4, 5].each #=> #<Enumerable::Enumerator:0xb7cc4040>
p [1, 2, 3, 4, 5].each_index #=> #<Enumerable::Enumerator:0xb7cc4004>
p [1, 2, 3, 4, 5].reverse_each #=> #<Enumerable::Enumerator:0xb7cc3fc8>
p [1, 2, 3, 4, 5].reject #=> #<Enumerable::Enumerator:0xb7cc3f8c>
p [1, 2, 3, 4, 5].reject! #=> #<Enumerable::Enumerator:0xb7cc3f50>
p [1, 2, 3, 4, 5].delete_if #=> #<Enumerable::Enumerator:0xb7cc3f14>
1.8.6 での挙動
p [1, 2, 3, 4, 5].collect #=> [1, 2, 3, 4, 5]
p [1, 2, 3, 4, 5].map #=> [1, 2, 3, 4, 5]
p [1, 2, 3, 4, 5].collect! #=> in `collect!': no block given (LocalJumpError)
p [1, 2, 3, 4, 5].map! #=> in `map!': no block given (LocalJumpError)
p [1, 2, 3, 4, 5].each #=> in `each': no block given (LocalJumpError)
p [1, 2, 3, 4, 5].each_index #=> in `each_index': no block given (LocalJumpError)
p [1, 2, 3, 4, 5].reverse_each #=> in `reverse_each': no block given (LocalJumpError)
p [1, 2, 3, 4, 5].reject #=> in `reject': no block given (LocalJumpError)
p [1, 2, 3, 4, 5].reject! #=> in `reject!': no block given (LocalJumpError)
p [1, 2, 3, 4, 5].delete_if #=> in `delete_if': no block given (LocalJumpError)
* Array#pop
* Array#shift
取り除く要素の数を指定できるようになりました。
例
a = [1, 2, 3, 4, 5]
a.pop #=> 5
p a #=> [1, 2, 3, 4]
p a.pop(3) #=> [2, 3, 4]
p a #=> [1]
1.8.7 用コードの 1.8.6 での挙動
a = [1, 2, 3, 4, 5]
p a.pop(3)
#=> in `pop': wrong number of arguments (1 for 0) (ArgumentError)
ArgumentError 例外が発生します。
* Array#choice
新しいメソッドです。配列からランダムに一つの要素を返します。
元の配列は変化しません。
http://doc.loveruby.net/refm/api/view/method/Array/i/choice
例
srand
a = [1, 2, 3, 4, 5]
p a.choice #=> 5
p a #=> [1, 2, 3, 4, 5]
1.8.7 用コードの 1.8.6 での挙動
srand
a = [1, 2, 3, 4, 5]
p a.choice
#=> undefined method `choice' for [1, 2, 3, 4, 5]:Array (NoMethodError)
メソッドが存在しないので NoMethodError 例外が発生します。
* Array#combination
新しいメソッドです。要素の組み合わせを列挙した配列を返します。
詳細は、http://doc.loveruby.net/refm/api/view/method/Array/i/combination
* Array#cycle
新しいメソッドです。要素を順番にブロックに渡しての評価を永遠に繰り返します。
詳細は、http://doc.loveruby.net/refm/api/view/method/Array/i/cycle
* Array#drop
新しいメソッドです。先頭から指定した数の要素を捨てた残りの配列を返します。
元の配列には影響を与えません。
詳細は、http://doc.loveruby.net/refm/api/view/method/Enumerable/i/drop
例
a = [1, 2, 3, 4, 5, 0]
p a.drop(3) #=> [4, 5, 0]
p a #=> [1, 2, 3, 4, 5, 0]
1.8.7 用コードの 1.8.6 での挙動
a = [1, 2, 3, 4, 5, 0]
p a.drop(3)
#=> undefined method `drop' for [1, 2, 3, 4, 5, 0]:Array (NoMethodError)
メソッドが存在しないので NoMethodError 例外が発生します。
* Array#drop_while
新しいメソッドです。要素を順番にブロックに渡して評価し、
その結果がはじめて真になるまでの要素を捨て、それ以降の要素からなる配列を
返します。
詳細は、http://doc.loveruby.net/refm/api/view/method/Enumerable/i/drop_while
例
a = [1, 2, 3, 4, 5, 0]
p a.drop_while{|i| i < 3 } #=> [3, 4, 5, 0]
1.8.7 用コードの 1.8.6 での挙動
a = [1, 2, 3, 4, 5, 0]
a.drop_while{|i| i < 3 }
#=> undefined method `drop' for [1, 2, 3, 4, 5, 0]:Array (NoMethodError)
メソッドが存在しないので NoMethodError 例外が発生します。
* Array#permutation
新しいメソッドです。要素の順列を列挙した配列を返します。
詳細は、http://doc.loveruby.net/refm/api/view/method/Array/i/permutation
* Array#product
新しいメソッドです。引数で与えた配列とのすべての組み合わせを列挙した配列を返します。
詳細は、http://doc.loveruby.net/refm/api/view/method/Array/i/product
* Array#shuffle
新しいメソッドです。シャッフルした配列を返します。元の配列には影響を与えません。
詳細は、http://doc.loveruby.net/refm/api/view/method/Array/i/shuffle
* Array#shuffle!
新しいメソッドです。破壊的にシャッフルします。
詳細は、http://doc.loveruby.net/refm/api/view/method/Array/i/shuffle=21
* Array#take
新しいメソッドです。先頭から指定した数の要素を返します。元の配列には影響を与えません。
詳細は、http://doc.loveruby.net/refm/api/view/method/Enumerable/i/take
例
a = [1, 2, 3, 4, 5, 0]
p a.take(3) #=> [1, 2, 3]
p a #=> [1, 2, 3, 4, 5, 0]
1.8.7 用コードの 1.8.6 での挙動
a = [1, 2, 3, 4, 5, 0]
p a.take(3)
#=> undefined method `take' for [1, 2, 3, 4, 5, 0]:Array (NoMethodError)
メソッドが存在しないので NoMethodError 例外が発生します。
* Array#take_while
新しいメソッドです。要素を順番にブロックに渡して評価し、
偽になるまでの要素を配列で返します。元の配列には影響を与えません。
詳細は、http://doc.loveruby.net/refm/api/view/method/Enumerable/i/take_while
例
a = [1, 2, 3, 4, 5, 0]
p a.take {|i| i < 3 } #=> [1, 2]
p a #=> [1, 2, 3, 4, 5, 0]
* Binding#eval
新しいメソッドです。自身のコンテキストで eval します。
詳細は、http://doc.loveruby.net/refm/api/view/method/Binding/i/eval
* Dir#each
* Dir.foreach
ブロックを与えなかった場合には Enumerator を返すようになりました。
例
p Dir.open(".").each #=> #<Enumerable::Enumerator:0xb7cea114>
p Dir.foreach(".") #=> #<Enumerable::Enumerator:0xb7cea0d8>
1.8.6 での挙動
p Dir.open(".").each #=> in `each': no block given (LocalJumpError)
p Dir.foreach(".") #=> in `foreach': no block given (LocalJumpError)
* Enumerable::Enumerator
新規ライブラリです。これを使用することで、each 以外のメソッドにも
Enumerable の機能を提供できます。
詳細は、http://doc.loveruby.net/refm/api/view/class/Enumerable=Enumerator
* Enumerable#each_slice
新しいメソッドです。n 要素ずつブロックに渡して繰り返します。
詳細は、http://doc.loveruby.net/refm/api/view/method/Enumerable/i/each_slice
* Enumerable#each_cons
新しいメソッドです。要素を重複ありで n 要素ずつに区切り、
ブロックに渡して繰り返します。
詳細、http://doc.loveruby.net/refm/api/view/method/Enumerable/i/each_cons
* Object#to_enum
* Object#enum_for
新しいメソッドです。自分を元に Enumerator を生成して返します。
なお、オブジェクトが each あるいは指定したメソッドを持っていなければ、
Enumerator は動作しません。
詳細は、http://doc.loveruby.net/refm/api/view/method/Object/i/enum_for
* Enumerable#count
* Enumerable#cycle
* Enumerable#drop
* Enumerable#drop_while
* Enumerable#find_index
* Enumerable#first
* Enumerable#group_by
* Enumerable#max_by
* Enumerable#min_by
* Enumerable#minmax
* Enumerable#minmax_by
* Enumerable#none?
* Enumerable#one?
* Enumerable#take
* Enumerable#take_while
新しいメソッドです。
詳細は、http://doc.loveruby.net/refm/api/view/class/Enumerable
* Enumerable#find
* Enumerable#find_all
* Enumerable#partition
* Enumerable#reject
* Enumerable#select
* Enumerable#sort_by
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* Enumerable#inject
ブロックの代わりに二項演算子をオプションで指定できるようになりました。
例
p (1..10).inject(:+) #=> 55
なお、二項演算子には +, -, *, /, %, **, &, |, ^, <<, >> が使えます。
* Enumerable#reduce
Enumerable#inject の別名です。
* Hash#eql?
* Hash#hash
* Hash#==
Array 同様、再帰的に判断するようになりました。
* Hash#delete_if
* Hash#each
* Hash#each_key
* Hash#each_pair
* Hash#each_value
* Hash#reject!
* Hash#select
* ENV.delete_if
* ENV.each
* ENV.each_key
* ENV.each_pair
* ENV.each_value
* ENV.reject!
* ENV.select
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* GC.stress
* GC.stress=
新しいメソッドです。
このフラグを true にすると、GC できる機会には必ず GC するようになります
(動作が非常に遅くなるので注意)。
拡張ライブラリ(や Ruby 本体)の不正なメモリアクセス発見といった
デバッグ目的で使用します。
詳細は、http://doc.loveruby.net/refm/api/view/class/GC
例
p GC.stress #=> false
GC.stress = true
p GC.stress #=> true
* Integer#ord
新しいメソッドです。1.9 コードの 1.8 互換性のために用意されました。
1.9 では ?a や "hoge"[0] は数値(Integer)ではなく文字列(String)を返します。
例
(ruby 1.8.x)
p ?a => 97
p "hoge"[0] #=> 104
(ruby 1.9)
p ?a => "a"
p "hoge"[0] => "h"
そのため、1.9 で文字コードの数値を得たい場合には、String#ord を使う必要が
あります。
p ?a.ord #=> 97
しかし、このコードを 1.8.6 で動かすと、
p ?a.ord #=> undefined method `ord' for 97:Fixnum (NoMethodError)
となってしまいます。そのため、1.8.7 では自分自身を返す Integer#ord が
追加されました。これによって 1.8.7 では 1.9 と同様に、
p ?a.ord #=> 97
と動作します。
* Integer#odd?
新しいメソッドです。奇数であれば true、偶数なら false を返します。
* Integer#even?
新しいメソッドです。偶数であれば true、奇数なら false を返します。
* Integer#pred
新しいメソッドです。自身から -1 した値を返します。名前の意味や使い道は良く分かりません。
* Integer#downto
* Integer#times
* Integer#upto
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* IO#each
* IO#each_line
* IO#each_byte
* IO.foreach
* ARGF.each
* ARGF.each_line
* ARGF.each_byte
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* Method#receiver
新しいメソッドです。レシーバを返します。
例
1.method(:to_s) #=> #<Method: Fixnum#to_s>
1.method(:to_s).receiver #=> 1
1.8.7 用コードの 1.8.6 での挙動
1.method(:to_s).receiver
#=> NoMethodError: undefined method `receiver' for #<Method: Fixnum#to_s>
メソッドが存在しないので NoMethodError 例外が発生します。
* Method#name
新しいメソッドです。メソッド名を返します。
例
1.method(:to_s).name #=> "to_s"
1.8.7 用コードの 1.8.6 での挙動
1.method(:to_s).name
#=> NoMethodError: undefined method `name' for #<Method: Fixnum#to_s>
メソッドが存在しないので NoMethodError 例外が発生します。
* Method#owner
新しいメソッドです。メソッドが定義されている class か module を返します。
例
"hoge".method(:id).owner #=> Kernel
1.8.7 用コードの 1.8.6 での挙動
"hoge".method(:id).owner
#=> NoMethodError: undefined method `owner' for #<Method: String(Kernel)#id>
メソッドが存在しないので NoMethodError 例外が発生します。
* UnboundMethod#name
新しいメソッドです。メソッド名を返します。詳細は Method#name 同様です。
* UnboundMethod#owner
新しいメソッドです。メソッドが定義されている class か module を返します。
詳細は Method#owner 同様です。
* Numeric#step
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* Object#instance_exec
新しいメソッドです。レシーバのコンテキストでブロック内を実行します。
オプション引数をブロック変数に渡せます。instance_eval との違いは
オプションを指定できるかどうかです(たぶん)。
例
class Hoge; def initialize; @a = 10; end; end
h = Hoge.new
h.instance_exec(1, 2){|x, y| p x + y + @a } #=> 13
1.8.7 用コードの 1.8.6 での挙動
class Hoge; def initialize; @a = 10; end; end
h = Hoge.new
h.instance_exec(1, 2){|x, y| p x + y + @a }
#=> NoMethodError: undefined method `instance_exec' for #<Hoge:0xb75f36d0 @a=10>
メソッドが存在しないので NoMethodError 例外が発生します。
* Object#tap
新しいメソッドです。self を引数としてブロックを評価し、self を返します。
例えばメソッドチェーンの途中の self を確認したいときに挟みます。
例
[1, 2, 3, 4, 5].map{|i| i * 2}.tap{|i| p i }.select{|i| i > 6}
#=> [2, 4, 6, 8, 10]
1.8.7 用コードの 1.8.6 での挙動
[1, 2, 3, 4, 5].map{|i| i * 2}.tap{|i| p i }.select{|i| i > 6}
#=> NoMethodError: undefined method `tap' for [2, 4, 6, 8, 10]:Array
メソッドが存在しないので NoMethodError 例外が発生します。
* ObjectSpace.each_object
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* Process.exec
新しいメソッドです。Kernel#exec の別名です。
* Range#each
* Range#step
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* Regexp.union
パターンを配列で受け取れるようになりました。
例
patterns = [/a/, /b/, /c/]
p Regexp.union(patterns) #=> /(?-mix:a)|(?-mix:b)|(?-mix:c)/
1.8.6 での挙動
patterns = [/a/, /b/, /c/]
p Regexp.union(*patterns) #=> /(?-mix:a)|(?-mix:b)|(?-mix:c)/
p Regexp.union(patterns) #=> TypeError: can't convert Array into String
Array を受け付けないので TypeError が発生します。
* String#bytesize
新しいメソッドです。1.9 コードの 1.8 互換性のために用意されました。
バイトサイズを返します。length や size の別名です。
なお 1.9 では、length や size は文字数、bytesize はバイト数を返します。
詳細は、http://doc.loveruby.net/refm/api/view/method/String/i/bytesize
例
"hoge".bytesize #=> 4
1.8.7 用コードの 1.8.6 での挙動
"hoge".bytesize
#=> NoMethodError: undefined method `bytesize' for "hoge":String
メソッドが存在しないので NoMethodError 例外が発生します。
* String#chars
* String#each_char
新しいメソッドです。
詳細は、http://doc.loveruby.net/refm/api/view/method/String/i/each_char
chars は each_char の別名です。
$KCODE を判断して、バイト単位ではなく文字単位で処理します。
* String#partition
新しいメソッドです。
詳細は、http://doc.loveruby.net/refm/api/view/method/String/i/partition
$KCODE を判断して、バイト単位ではなく文字単位で処理します。
* String#rpartition
新しいメソッドです。
詳細は、http://doc.loveruby.net/refm/api/view/method/String/i/rpartition
$KCODE を判断して、バイト単位ではなく文字単位で処理します。
* String#start_with?
新しいメソッドです。
詳細は、http://doc.loveruby.net/refm/api/view/method/String/i/start_with=3f
$KCODE を判断して、バイト単位ではなく文字単位で処理します。
* String#end_with?
新しいメソッドです。
詳細は、http://doc.loveruby.net/refm/api/view/method/String/i/end_with=3f
$KCODE を判断して、バイト単位ではなく文字単位で処理します。
* String#each_byte
* String#each
* String#each_lines
* String#gsub(pattern)
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* StopIteration
新しい例外クラスです。Kernel#loop を停止できます。
例
loop {
p "lorem ipsum"
raise StopIteration
}
#=> "lorem ipsum"
1.8.6 での挙動
loop {
p "lorem ipsum"
raise StopIteration
}
#=> uninitialized constant StopIteration (NameError)
クラスが存在しないので NameError が発生します。
* Struct#each
* Struct#each_pair
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* Symbol#to_proc
新しいメソッドです。
詳細は、http://doc.loveruby.net/refm/api/view/method/Symbol/i/to_proc
* __method__
新しい組み込み関数です。今いるメソッドの名前をシンボルで返します。
例
def test
p __method__
end
alias hoge test
test #=> :test
hoge #=> :test
1.8.7 用コードの 1.8.6 での挙動
def test
p __method__
end
alias hoge test
test #=> NameError: undefined local variable or method `__method__' for main:Object
組み込み関数(メソッド)が存在しないので NameError が発生します。
* enumerator
* Enumerator は組み込みモジュールになりました。
#next と #rewind は generator ライブラリを使って実装されています。
パフォーマンス悪化に注意して使ってください。
* ipaddr
* 新しいメソッド
* IPAddr#<=>
* IPAddr#succ
これらのメソッドにより、IPAddr オブジェクトは comparable で
enumerable になりました。また、二つの IPAddr オブジェクトの間の
Range オブジェクトを作ることもできます。
* IPAddr#to_range
ネットワークアドレスの Range オブジェクトを作成するメソッドです。
* 型強制をサポート
* IPAddr#&
* IPAddr#|
* IPAddr#==
* IPAddr#include?
これらのメソッドは IPAddr オブジェクトの代わりに文字列や整数を
受け付けます。
* net/smtp
* SSL/TLS をサポートしました。
* openssl
* 新しいクラス
* OpenSSL::PKey::EC
* OpenSSL::PKey::EC::Group
* OpenSSL::PKey::EC::Point
* OpenSSL::PKey::PKCS5
* OpenSSL::SSL::Session
* ドキュメント
* いくつかの新しいメソッド
* Cipher、Digest、PKCS7、PKCS12 内の冗長なモジュールによる名前空間を削除しました。
互換性のためのクラスを提供します(Ruby 1.9 では削除されます)。
* shellwords
* シェルにとって安全でない文字をエスケープするメソッドを追加:
* Shellwords.join http://doc.loveruby.net/refm/api/view/method/Shellwords/s/join
* Shellwords.escape http://doc.loveruby.net/refm/api/view/method/Shellwords/s/escape
* Array#shelljoin http://doc.loveruby.net/refm/api/view/method/Array/i/shelljoin
* String#shellescape http://doc.loveruby.net/refm/api/view/method/String/i/shellescape
* 短縮形式のメソッドを追加:
* Shellwords.split (shellwords の別名) http://doc.loveruby.net/refm/api/view/method/Shellwords/s/split
* String#shellsplit http://doc.loveruby.net/refm/api/view/method/String/i/shellsplit
* stringio
* StringIO#getbyte
* StringIO#readbyte
新しいメソッドです。1.9 前方互換性のための別名です。
* StringIO#each_char
* StringIO#chars
新しいメソッドです。String#each_char と同じ。
* StringIO#each
* StringIO#each_line
* StringIO#each_byte
ブロックが与えられなかったときには、enumerator が返されるようになりました。
* tempfile
* Tempfile.open と Tempfile.new は一時ファイル作成のための拡張子を
指定できるようになりました。拡張子を指定するには、[basename, suffix]
という形式の配列を第一引数に渡してください。
Tempfile.open(['image', 'jpg']) { |tempfile| ... }
* uri
* LDAPS スキーマが追加されました。
* RFC3986 に準拠するための修正が行われました:
* FTP
* URI('ftp://example.com/foo').path #=> 'foo'
* URI('ftp://example.com/%2Ffoo').path #=> '/foo'
* URI::FTP.build([nil, 'example.com', nil, '/foo', 'i').to_s #=> 'ftp://example.com/%2Ffoo;type=i'
* URI の結合
* URI('http://a/b/c/d;p?q').merge('?y') == URI('http://a/b/c/d;p?y')
* URI('http://a/b/c/d;p?q').merge('/./g') == URI('http://a/g')
* URI('http://a/b/c/d;p?q').merge('/../g') == URI('http://a/g')
* URI('http://a/b/c/d;p?q').merge('../../../g') == URI('http://a/g')
* URI('http://a/b/c/d;p?q').merge('../../../../g') == URI('http://a/g')
* rss
* バージョンが 0.1.6 から 0.2.4 に変更されました
* image モジュールの URI を修正しました
* Atom をサポートしました
* ITunes モジュールをサポートしました
* Slash モジュールをサポートしました
* RSS 2.0 内の content:encoded をサポートしました
=== インタプリタ実装
* Proc にブロックを渡す [実験的機能]
現在の実装はバグが含まれており上手く機能しません(特にネストしたブロックの呼び出し)。
実験的な機能として扱ってください。
* スタックトレース
システムスタックエラー以外の例外では、省略せずにすべてのスタックトレースが
表示されるようになりました。
=== 互換性問題(バグ修正含む)
* String#slice! はいくつかの意図しないバグがあり、修正されています。
残念ながら、以下のややまれなケースで非互換を引き起こしています。
* #slice! は配列の大きさを超えた値を与えられても配列を拡張しなくなりました。
# Ruby 1.8.6
a = [1,2]
a.slice!(4,0) #=> nil
a #=> [1,2,nil,nil]
# Ruby 1.8.7
a = [1,2]
a.slice!(4,0) #=> nil
a #=> [1,2]
* #slice! は負の長さや境界を超える負の位置が与えられても例外を
上げなくなりました。代わりに nil を返します。
# Ruby 1.8.6
a = [1,2]
a.slice!(1,-1) #=> (raises IndexError)
a.slice!(-5,1) #=> (raises IndexError)
# Ruby 1.8.7
a = [1,2]
a.slice!(1,-1) #=> nil
a.slice!(-5,1) #=> nil
* String#to_i、String#hex、String#oct は連続したアンダースコア (`__') を
受け付けなくなりました。
# Ruby 1.8.6
'1__0'.to_i #=> 10
'1__0'.to_i(2) #=> 2 # 0b10
'1__0'.oct #=> 8 # 010
'1__0'.hex #=> 16 # 0x10
# Ruby 1.8.7
'1__0'.to_i #=> 1
'1__0'.to_i(2) #=> 1
'1__0'.oct #=> 1
'1__0'.hex #=> 1
1.8.6 での挙動は Ruby の構文と一貫性がなくバグと思われるためです。
なお、連続しないアンダースコア (`_') の場合には、ちゃんと一つの数字とみなします。
これは数値リテラルの仕様(http://www.ruby-lang.org/ja/man/html/_A5EAA5C6A5E9A5EB.html#a.bf.f4.c3.cd.a5.ea.a5.c6.a5.e9.a5.eb)に合わせた挙動です。
# Ruby 1.8.7
'1_0'.to_i #=> 10
* date
* Date.parse
'##.##.##' (各 '#' は数字) は、 'MM.DD.YY' ではなく 'YY.MM.DD' と
解釈されます。この変更で問題が生じる場合には、Date.strptime を
用いてください。
* stringio
* StringIO#each_byte
戻り値が nil から self に変わりました。
ドキュメントの記述と each_line の挙動に合わせています。
* tempfile
* ファイル名の形式が変更されました。デフォルトでは一時ファイル名に
ドット (`.') が含まれなくなりました。
* tmpdir
* 新しいメソッド
* Dir.mktmpdir http://doc.loveruby.net/refm/api/view/method/Dir/s/mktmpdir
* uri
* 詳細は上記参照
John Lam on Software: IronRuby and Rails によれば、
IronRuby dispatched some simple requests through an unmodified copy of Rails a few days ago. Today, we’re going to show off our progress live at RailsConf.
ということで、RailsConf でデモをしたみたいです。しかし、すっかりRails が Ruby 処理系の成熟度の指標になってますね。
関連するニュース記事ですと、
などと Silverlight と Rails という見出しですが、単に IronRuby 処理系で Rails が動くというのと、Silverlight が Rails と連携するというのではちょっとニュアンスが違う気もします。どっちも DLR 環境で動くという点では同じですが、後者だと積極的にサポートするように聞こえますね。
安価で尋問スレ9(78) ○○殺人事件の裁判員だけど質問ある?Part10(48) 【有罪】代わりに決めてくれ第3審【無罪】(201) サイバンインコ(7) 【犬が】裁判員の逃れ方指南その12【食べました】(14) やる夫が裁判員をやるようです(67) 日当いくらもらえるの?(397) □□裁判所の××裁判官は氏ね(11)
秘密保持義務がどのくらい深刻かによりますが、あんまり厳しくないなら↑のようになるんじゃないかと。ある意味で国民にひらけた裁判になりますね。法廷の内部や裁判官など法廷関係者個々人の情報がネットで共有されるようになるでしょうから。
裁判員制度は2009年5月21日に法が施行される予定です。つまり後一年弱です。今まであまり関心がなかったのですが、妻の勧めで何冊か本を読んだ結果、少し危機感を持っています。このままでは制度上の問題が多く残ったまま施行されて、裁判員に選ばれる人も被告人も犯罪被害者も不利益を被るのではないかと。
まだ反対派の本しか読んでいないので、推進派の本やサイトも読まないと結論は決められませんが、反対派の方に分がありそう。
特定ベンチでは……って東スポの見出しみたいですが。
MagLev は、Ruby that scales™をトレードマークに Railsconf でお披露目がされた Ruby 処理系です。先日行われたrailsconf2008 ではかなり注目されたみたいですね。
コードはまだ一般には公開されていません。Ruby 初の商用処理系になるのかな。ChadFowler.com Maglev あたりを読むに、まだ Ruby 処理系としては完成度が低く、WEBRick がやっと動いたというくらいみたいです。
Ruby 処理系のベンチマークThe Great Ruby Shootoutをしてる Antonio Cangiano が MagLev handles trees like a monkey という記事を書いています。その記事中に binary-trees test のベンチ結果が載っています。Ruby 1.8.6 の 8 倍くらいはやく、Python の 4 倍くらいはやく、なんと C++(gcc)より 2 割遅いだけです。俄かに信じがたいですね。
記事についたコメントを追っていくと、他のベンチではどうなんだというものがあり、それに対して Antonio Cangiano は I couldn’t run Fasta, but I was able to run, by implementing a method of the Array class on my own, Fannkuch.
と応えてます。結果は元記事で確認してほしいですが、まあ妥当な感じの値になってます。足りないメソッドを自分で実装しているというので、いずれもっと最適化されるんじゃないかとは思いますけれど。
日本語の情報で一番詳しいのは、sumim さんのMagLev について調べてみた - sumim’s smalltalking-tos です。まずここから。
また、railconf2008 での MagLev プレゼンへの MagLev 反応リンク集もあります。あと、サイト によれば Railsconf でのプレゼンのビデオを公開する予定のようなので、それを見ればもう少し詳しいことが分かるんじゃないかと思います。
Nome do Jogo » Artigo » New Free Book: “Ruby on Rails 2.1 - What’s new”で、Rails 2.1 での変更点をまとめた PDF が公開されています。126 ページ(後半は changelog の引き写しですが)の労作です。新機能を確認する目的には詳細過ぎますが、細かい挙動の変化まで確認したい人には良いと思います。
しかし、Rails 2.1 はいつ試そうかなあ……
公式サイトにはまだアナウンスがありませんが、最新の安定版 1.8.7 のパッチリリースが一昨日でました。1.8.7 を使っている方はバージョンアップしましょう。
以下、Ruby のリリースエンジニアリングについての説明です。p17 って何という人向けです。
6/1 にリリースされた 1.8.7 と 1.8.7-p17 との関係はなんでしょうか。これは、MUSHA さんの 1.8.7-p17 リリースアナウンスが端的で分かりやすいです。
本リリースは 1.8.7 リリース後に見つかった問題の修正を目的とするパッチリリースであり、安定性と互換性が向上しています。
Ruby 1.8.7-p17 has been released
1.8.7 に対してバグ修正が施されたバージョンだということがわかります。では、p17 とは一体なんでしょうか。これはパッチレベルを意味します。
パッチレベルの話の前にメンテナンス体制について書きます。
Ruby はバージョン 1.8.5 あたりからメンテナンス体制が強化されました。リリースされた 1.8.x (現在であれば 1.8.6 と 1.8.7)と、開発中の 1.8 (現在であればいずれ 1.8.8 になるもの)それぞれに担当のメンテナがいて、バグ修正、脆弱性修正、仕様変更、新機能追加やリリース計画について取りまとめています。
リリースしたバージョンにバグが見つかったとします。例えば、今回は 1.8.7 で Rails 2.0.2 のアプリを動かす際に問題が起きました。1.8.4 以前であればバグが修正されたとしても、「1.8 の最新版では直っているので、CVS から head を取り出して使ってくれ」という対応で、あまりユーザフレンドリーとは言えませんでした。1.8.5 以降は 1.8.x-pxx として公式にリリースしていますので、ダウンロードすべき「最新の安定版」が明確になりましたし、「アップデートすべきなのか」「どのような修正があったのか」も分かりやすくなりました。
このメンテナンス体制については、Ruby 1.8 - ReleasePlanJa - Ruby Issue Tracking System にテキストがありますので、興味のある方は読んでみて下さい。
さて、パッチレベルについてです。上述の ITS のテキストから引用します。
適用されたパッチの数をパッチレベルという数値がカウントしている。パッチレベルは各ブランチごとに0から始まり、パッチを当てるごとに1ずつ増える。パッチレベル付きのバージョンをRuby 1.8.5-p115のように表記することがある。
Ruby 1.8 - ReleasePlanJa - Ruby Issue Tracking System
6/1 にリリースされた 1.8.7 はパッチレベル付きで表記すると 1.8.7-p0 です。一昨日リリースされたのが 1.8.7-p17 ですので、17 個のパッチがあたっているわけです。
どのような修正がなされたかは、ChangeLogで分かります。また、Ruby 1.8.7 - リビジョン - Ruby Issue Tracking Systemを見れば、それぞれのパッチで行われたコード変更が具体的にどのような内容かも分かります。
Ruby Enterprise Editionは、Phusion Passenger (mod_rails) の Phusion による、GC がチューニングされた Ruby です。
Allows your Ruby on Rails applications to use 33% less memory on average, when used in combination with Phusion Passenger.
ということで、メモリ使用効率が良いようです。
ソースを確認したところ、Ruby 1.8.6-p114 をベースにしています。1.8.6 の最新版ですね。diff を取ってみたところ、GC 周りのみ手が入っていました。また、vendor ディレクトリ以下に google-perftools と libunwind が追加されています。プロファイリングのためのようです。
GC への変更ですが、Matzにっき(2008-02-05) -Copy-on-write friendly patch for Ruby 1.9で触れられている copy-on-write friendly にするための修正のようです。赖洪礼的 blog » Making Ruby’s garbage collector copy-on-write friendly, part 7 では、GC の実行時間短縮を謳ってますが、Ruby Enterprise Edition ではメモリ消費削減を前面に押し出してますね。ケースによって効果が変わってくるでしょうから、もう少し詳細なベンチマーク結果がほしいところです。
大学生のころから家計簿をつけているのですが、そろそろデスクトップアプリじゃなくてウェブアプリに移行したいと思ってます。いまは、家計簿ひかるを使っていて機能的には不満は無いのですが、家の PC 以外や携帯で入力したり参照できるといいなあと。
要件としては、
といったところ。はてなの質問などで適当に探してみました。
さてどうしたものか。
Spread Firefox | Download Day 2008には、Firefox 3 の正式リリース日は 2008 年 6 月 17 日です。
とありますが、これは太平洋夏時間によるものです。日本時間では、Mozilla Japan ブログ - Firefox 3 Download Day は 6月18日!!とのこと。
Firefox Twitter によれば、
Download Day starts at 10:00 a.m. Pacific Daylight Time on Tuesday, June 17th. For local times see: http://tinyurl.com/4e7fv5
Twitter / Firefox: Download Day starts at 10:0...
とのことです。日本時間では 6/18(水) 02:00 から 6/19 (木) 02:00 の 24 時間ですね。
後学のため、1.8.7-p17 の修正点を調べてみました。手順は単純で以下の通りです。
バグが報告されている場所が複数あり、情報を調べるにも手間でした。開発者の方はあちこちを見ていないといけないので大変ではないでしょうか。redmine が順調に稼動すればバグは集約されてこのような手間が減りそうです。
おそらく探し方が悪いのだと思いますが、議論や修正理由が追えないものがありました。コミットログに ML 番号が書いてないと無理ですね。すべてのコミットに対応する redmine のチケットが存在する状態だと、後から追えていいです。
delegate したクラスのインスタンスを Marshal.dump しようとするとエラーになります。
[ruby-core:17045] [ruby-dev:34938]
Object#respond_to? がオプション引数として include_private(デフォルト false)を取るようになりましたが、標準添付ライブラリの delegate がその変更に追随してませんでした。1.8.7 で Marshal の内部処理が少し変更されたため問題が表明化しました。
delegate したクラスを Marshal.dump したときに再現します。再現コードは、[ruby-core:17045] 参照のこと。
strscan を使わないで erb を使うとエラーが発生します。
strscan を使わずに erb を使うと発生します。再現コードは、[ruby-core:17033] 参照のこと。
enumerator 作成時のエラーチェック強化。たぶん Ruby レベルでは影響ありません。
これも enumerator 作成時のエラーチェック強化。たぶん Ruby レベルでは影響ありません。
Iconv#iconv の挙動がドキュメントと異なります。
Iconv#iconv の第一引数に String を与えると再現します。再現コードは、[ruby-core:17092] 参照のこと。しかし、これまで誰も使ってなかったんでしょうかという疑問が……
特定のバージョン&ビルドオプションの OpenSSL を使用時に test-all すると openssl でエラーになります。
--enable-tlsext でビルドされた 0.9.8f 以降の OpenSSL を 使っている場合。
細々としたバグ修正 4 件。
[ruby-Bugs:20528] [ruby-Bugs:20504] [ruby-core:17073] [ruby-doc:1026]
Cygwin 環境で存在しないファイルなどに対して File.expand_path を実行すると正しく動作しません。
Cygwin 環境で存在しないファイルなどに対して File.expand_path を実行すると再現します。再現コードは、[ruby-talk:303736] 参照のこと。
コンパイル時の警告の削減とセキュリティ向上のための修正です。
Visual C++ 8 で Winsock2 を使ってビルドするときの問題の修正です。
特定環境・条件時に IO.open でエラーになる可能性があります。
mode が unsigned int な環境で、mode にやたら大きな値を指定して、IO.open した場合。普通にプログラム書いていて、この条件に引っかかることはあるのかな?
GC のスキャンヒープが不用意に開放されないような修正のようです。どういう時に再現するかなどは不明。
configure スクリプトの修正。sitedir と vendordir に PREFIX ではなく LIBDIR を使うように。
Hash#hash がハッシュ内の要素の順番を気にしないようになりました。
こういう感じで Hash が配列の中などに使われているときに影響してきます。
$ ruby18 -v -e '
a = [{1 => 2, 2 => 3}]
b = [{2 => 3, 1 => 2}]
p a.eql?(b)
'
ruby 1.8.6 (2008-03-03 patchlevel 114) [i686-linux]
false
$ ruby187 -v -e '
a = [{1 => 2, 2 => 3}]
b = [{2 => 3, 1 => 2}]
p a.eql?(b)
'
ruby 1.8.7 (2008-06-16 patchlevel 5000) [i686-linux]
true
Zlib::Deflate オブジェクトの clone メソッドを呼ぶとエラーになります。
再現コードは [ruby-list:45016] 参照のこと。
set ライブラリへの修正。
Ruby 会議 0 日目ですが、任意のコードが実行される脆弱性についてということで、各バージョンのセキュリティフィックスがリリースされました。
1.9.0-2 は元々 Ruby 会議に合わせてリリースが予定されていましたが、これだと脆弱性修正のリリースにしか見えませんね。
つくばエクスプレスが速いのに感動しました。家から乗り換えなしの一本で行けるのもポイント高いです。
後ろの円卓でフリーダムにパソコン使ってました。Code Golf してて講演を聞き流し気味ですみません。おかげさまでRubyKaigi2008 Golfコンペでは、パーより少し上くらいのスコアを取れ、賞品として Ruby クックブックをもらいました。まあ、現地の参加者よりも賞品の方が多かったので、参加者全員が賞品をもらえたんですけども。
0 日目は、スポンサーセッションとコミュニティ紹介がメインで、Ruby の広がりが実感できる一日だったと言えます。個人的には、ブームを裏で下支えした経験をもって Linux ブームと Ruby ブームとを比較して語る CTC の講演「エンタープライズRubyと Linuxブームのちがい」が興味深かったです。
コミュニティのボランティアベースならではのアットホーム感というかゆるい雰囲気で進行していましたが、MySQL カンファレンスを見てきた身からすると、もっと企業受けをするパフォーマンスなりイベントを盛り上げるための演出があるといいなと思わないでもありません。もちろんそれはボランティアベースのイベントとは性質が異なるので、Ruby会議とは別にオライリーのようなイベントのプロが手がけるべきですが。
ノベルティの一つは無地のエコバッグでした。これは、今年の Ruby 会議のキーワード「多様性」を考えるための企画です。参加者それぞれの 「Ruby」をエコバッグ上で表現しようという趣旨です。会場にスタンプがおいてあるので、思い思いに押して自分なりの Ruby エコバッグを作ります。最初もらったときは「ただの袋?ノベルティはどこに?」と思いましたが(笑 趣旨を聞けばなるほどなと思いました。
妻が消しゴムハンコ職人なので、Ruby ロゴのハンコを作ってもらいました。インクがほどよく掠れて良い塩梅です。
せっかくなのでハンコは明日会場に持って行きます。
上に書いたハンコですが、スタッフにお願いして置かせてもらいました。よかったら使ってみてください>会場の方。
最近のコメント:
RSS
![]()
This work is licensed under a
Creative Commons License
(note: text only. w/o web design, citations, (re)distributed softwares).
_ rubikitch [Enumerable#enum_cons, Enumerable#enum_sliceは削除されるため、NEWSから..]
_ だて [ありがとうございます。preview4 ベースで作業していたので残ってました。]
_ musha [翻訳・まとめ・加筆ありがとうございます。 Array#delete_if は1.8.7リリース前にenumer..]
_ だて [すみません。修正しました。]