2007年12月01日 18:45 [Edit]

LLいろいろ、スコープいろいろ

このスコープの「レキシカルさ加減」が、実は言語によって結構違うので、この機会にちょっとつっこんでおくことにする。

ハタさんのブログ : javascriptを初めて学ぶ人についてのおさらい。その1
変数で宣言したものには、参照先が決まっています。その参照の範囲はスコープとも呼びます。

ここでいきなり問題。以下のコードは何をalertするでしょうか?

(function(){
  var i = -1;
  for(var i = 0; i < 10; i++){
    /* whatever */
  }
  alert(i);
})()

これが-1でないのは、Perl Mongerにはびっくりです。

sub test{
  my $i = -1;
  for my $i (0..9){ 
  }
  warn $i
}
test();
% perl scope.pl 
-1 at scope.pl line 5.

ところが、pythonもrubyも、この点においてはむしろJavaScriptに近い挙動を示します。

def test():
  i = -1
  for i in range(0,10):
    pass # do nothing
  print i;

test()
% python scope.py
9
def test
  i = -1
  (1..9).each do |i|
  end
  puts i
end
test
% ruby scope.rb 
9

特にrubyのブロック引数がブロックローカルではない点は、オレオレ詐欺に引っかかったようなみじめさを感じさせずにいられません。

ちなみに、JavaScript 1.7では、let宣言が導入されたので、

(function(){
  var i = -1;
  for(let i = 0; i < 10; i++){
    /* whatever */
  }
  alert(i);
})()

-1alert()するようになるとJohn Resigが一押ししてくれていたが、普及にどれくらいかかるのだろう。

Dan the Block Scope Advocate


この記事へのトラックバックURL

この記事へのトラックバック
良記事は補足して育てよう。 現代的なPerlの記述方法一覧 + α - Perl入門〜サンプルコードによるPerl入門〜 補足するのは、$_の使いどころについて。
#perl and more - $_ とスコープ【404 Blog Not Found】at 2009年11月01日 22:44
これは、同感、というより、 おごちゃんの雑文 ? Blog Archive ? プログラム言語に「わくわく」なんていらんでしょ逆にRubyは「わくわく」しない言語だった。だからこそRubyな人達が「わくわく」と言うのに違和感を感じるんだけど。じゃあなぜ「わくわく」しないかと言えば....
言語にわくわくが必要な理由【404 Blog Not Found】at 2008年06月23日 05:01
our 名前をスコープに限定.local 値をスコープに限定.my 名前と値の両方をスコープに限定 すっきりした>< - YoshioriのBlog これはperlの話だけど、最近dankogai氏が言語毎の挙動を列挙してたな。 →404 Blog Not Found:LLいろいろ、スコープいろいろ 視認性を良くするた
[Perl] Perlのourとlocalとmyの違い【suzukyuの勉強日記】at 2008年01月11日 10:41
JSTだと日付をまたいじゃったけど、GMTならまだ間に合うということで。 Ruby 1.9.0リリース @ 2007年12月 @ ratio - rational - irrational @ IDMRuby 1.9.0がリリースされました。恒例のクリスマスリリースです。開発者のみなさん、お疲れ様でした。 Ruby 1.9.0...
ruby - 1.9.0 Released!【404 Blog Not Found】at 2007年12月26日 02:26
この記事へのコメント
Javascript では with 使えばブロックスコープできるそうです。

http://nanto.asablo.jp/blog/2006/07/08/437419
Posted by ■□ Neon / himorogi □■ at 2007年12月02日 12:05
PHP でも 10 になりました。

<?php
function test()
{
$i = -1;
for ($i = 0; $i < 10; $i++) {
}
echo $i;
}

test();
?>
Posted by Passer-by at 2007年12月02日 11:35
javascriptの場合、blockはscopeを作らないのでPythonやrubyとは意味が異なるのではないでしょうか?
ECMAScript Language Specification(3rd edition)
12.2 Variable statement
Description
If the variable statement occurs inside a FunctionDeclaration, the variables are defined with function-local scope in that function, as described in 10.1.3. Otherwise, they are defined with global scope (that is, they are created as members of the global object, as described in 10.1.3) using property attributes { DontDelete}. Variables are created when the execution scope is entered. A Block does not define a new execution scope. Only Program and FunctionDeclaration produce a new scope. Variables are initialised to undefined when created.
Posted by かめぞう at 2007年12月02日 06:14
10でいいんでは?( i=0; while(i<10){/* ... */; i++;} なら )
Posted by ae at 2007年12月02日 03:16
自分のインターネッツブラウザでは「実行」を押すと10になるな。
へんなの。
Posted by むむむ at 2007年12月02日 00:03
だからこういう「なんかかぶってそう」な変数名に
視覚レベルで違和感をおぼえるオレは
有能なプログラマにちがいないんだぜ?
Posted by すがりもの at 2007年12月01日 22:29
Ruby1.9では-1になりますよ
Posted by naruse at 2007年12月01日 20:30
宣言がない言語(RubyやPerl)は、それらがあるPerlともJavaScriptとも違う振る舞いをするのは当然だと思うんですけど。

ところで、Ruby 1.9ではブロックパラメータはブロックローカルになります。
Posted by まつもと at 2007年12月01日 20:28