以下の ruby スクリプトを実行するとどうなるでしょう?
#!/usr/bin/env ruby # coding: utf-8 a = "hoge" if true printf "%s if の中 %s\n", *(["*" * 10] * 2) puts "a: #{a}" b = "piyo" puts "b: #{b}" end printf "%s if の外 %s\n", *(["*" * 10] * 2) puts "a: #{a}" puts "b: #{b}"
なんと、以下のような結果になります:
********** if の中 ********** a: hoge b: piyo ********** if の外 ********** a: hoge b: piyo
“if の中で定義した変数は、if の外からアクセスできないだろう” と思い込んでいたので、ショックでした。
どうしても新しいスコープを開きたければ、proc とかを代用すればいいのかも知れません:
#!/usr/bin/env ruby # coding: utf-8 a = "hoge" proc do if true printf "%s if の中 %s\n", *(["*" * 10] * 2) puts "a: #{a}" b = "piyo" puts "b: #{b}" end end.call printf "%s if の外 %s\n", *(["*" * 10] * 2) puts "a: #{a}" puts "b: #{b}"
実行結果:
********** if の中 ********** a: hoge b: piyo ********** if の外 ********** a: hoge hoge.rb:17:in `<main>': undefined local variable or method `b' for main:Object (NameError)
そもそも a とか b とか、簡単に衝突するような安易な変数名を使わなければいいんですけどね!
ちなみに…
Perl の場合:
#!/usr/bin/perl use strict; use utf8; binmode STDOUT, ":utf8"; my $a = "hoge"; if (1) { printf("%s if の中 %s\n", (("*" x 10) x 2)); print "a: $a\n"; my $b = "piyo"; print "b: $b\n"; } printf("%s if の外 %s\n", (("*" x 10) x 2)); print "a: $a\n"; print "b: $b\n";
実行結果:
********** if の中 ********** a: hoge b: piyo ********** if の外 ********** a: hoge b:
perl には my ちゃんがいるので便利ですね。
C の場合:
#include <stdio.h> int main(void) { char *a = "hoge"; if (1) { char *b = "piyo"; printf("********** if の中 **********\n"); printf("%s\n", a); printf("%s\n", b); } printf("********** if の外 **********\n"); printf("%s\n", a); printf("%s\n", b); return 0; }
コンパイルエラーです:
hoge.c: In function ‘main’: hoge.c:16: error: ‘b’ undeclared (first use in this function) hoge.c:16: error: (Each undeclared identifier is reported only once hoge.c:16: error: for each function it appears in.)
python の場合:
#!/usr/bin/python # coding: utf8 a = "hoge" if True: print "%s if の中 %s" % (("*" * 10,) * 2) print "a: " + a b = "piyo" print "b: " + b print "%s if の外 %s" % (("*" * 10,) * 2) print "a: " + a print "b: " + b
なんと、ruby と同じ挙動です:
********** if の中 ********** a: hoge b: piyo ********** if の外 ********** a: hoge b: piyo
php でもやってみました:
<?php $a = "hoge"; if (true) { call_user_func_array("printf", array_merge(array("%s if の中 %s\n"), array_fill(0, 2, str_repeat("*", 10)))); echo "a: {$a}\n"; $b = "piyo"; echo "b: {$b}\n"; } call_user_func_array("printf", array_merge(array("%s if の外 %s\n"), array_fill(0, 2, str_repeat("*", 10)))); echo "a: {$a}\n"; echo "b: {$b}\n";
ruby, python と同様でした:
********** if の中 ********** a: hoge b: piyo ********** if の外 ********** a: hoge b: piyo
スコープも言語によって色々ですね。気づきにくいところなので厄介です。
(コウヅ)
- 格安マネージドサーバーはエムアンドティー
- 格安企業認証 SSL はデジトラスト
- 格安ドメイン認証 SSL はエコサート
- レンタルサーバーと SSL 証明書を徹底比較
- 簡単で便利なサーバー監視の SaaS
広告