[#48450] 1.8.7と1.9.2の挙動の違いについて — "Jun'ya Shimoda" <jun-shimo@...>

下田です。

13 messages 2011/10/09

[ruby-list:48437] Re: WEBrick

From: "Y. Nobuoka" <nobuoka@...>
Date: 2011-10-04 02:37:34 UTC
List: ruby-list #48437
牛坂さん

信岡です。

> [ruby-list:48432] を読みました。
> *を仮引数につけて配列をバラスのであれば、以下のように逆になるのでは。

* を付けることで配列をばらすのは仮引数の方ではなく実引数の方です。
仮引数と実引数で * を付けることの意味が違うので、ちょっとややこしいかもしれません。
[ruby-list:48432] の繰り返しになりますが、仮引数に * を付けた場合の動きと
実引数に * を付けた場合の動きを以下に示します。

仮引数 (メソッドの定義側) の変数名の前に * を付けた場合、任意個数の
実引数が 1 個の配列にまとめられ、1 つの仮引数として受け取ることができます。

 def test1( *args )
   p args
 end
 test1( :a, :b )
     # メソッド test1 中の args は [ :a, :b ] という配列を参照する

一方、メソッド呼び出し時に引数の配列の前に * を付けると、配列の各要素が
実引数としてメソッドに渡されます。

 def test2( arg1, arg2 )
   p arg1, arg2
 end
 test2( *[ :a, :b ] )
     # メソッド test2 中の arg1 は :a, arg2 は :b を参照する

詳しくは以下の web ページを見てください。
 http://ruby-doc.org/docs/ProgrammingRuby/html/tut_methods.html

ここで、今回の
     File.join( document_root, *req.path.split( '/' ) )
を考えてみます。 実引数側にも仮引数側にも * が付いているのでややこしいのですが、
分かりやすいように上で定義したメソッド test1 を使うと
     File.join( document_root, *req.path.split( '/' ) )
は
     test1( :a, *[ :b, :c ] )
と類似であり、
     File.join( document_root, req.path.split( '/' ) )
は
     test1( :a, [ :b, :c] )
と類似であるといえます。
(類似、というのは、実引数および仮引数の * の使い方に関してのみの話です。)
前者では、メソッド test1 中の args が [ :a, :b, :c ] となり、
後者では [ :a, [ :b, :c ] ] となります。
そんなわけなので、
      File.join( document_root, *req.path.split( '/' ) )
が
     ( [ document_root ] + req.path.split( '/' ) ).join( File::SEPARATOR ) # (1)
と同じ、ということで間違いないと思うのですがいかがでしょうか。

長々と書いてしまいましたが、実際にコードを書いて実行してみるのが
一番分かりやすいと思いますので、このメールに書いたサンプルコードなど
を試してみてください。

-- 
信岡 ゆう (NOBUOKA Yu)

In This Thread