はじめに
職務上、さまざまなプログラミング言語を扱うことがあるのですが、言語によって文法や挙動の違いに戸惑ったり、うっかりミスをしたりすることがあります。でも、1つの言語だと当たり前に思ってしまうことも、複数の言語を並べることで、逆によく見えてくることもあります。この記事では、Delphi、C++、Java、C#、PHP、Rubyの6言語を取り上げ、同じような動作を記述していながら、結果が異なるケースを紹介し、言語ごとの挙動の違いを考察します。
最初のクイズ(変数のスコープ)
問題
最初のクイズは、変数のスコープに関するものです。グローバル変数やstaticなメンバを使ったコードを6つの言語で書いてみましたが、1つだけ出力結果が違うものがありました。それはどれでしょうか?
program Project1; {$APPTYPE CONSOLE} var x: Integer; procedure test; begin Write(x); end; begin x := 1; test; end.
#include <iostream> int x; void test() { std::cout << ::x; } int main(int argc, char* argv[]) { ::x = 1; test(); return 0; }
package project1; public class Project1 { public static void test() { System.out.print(x); } public static void main(String[] args) { x = 1; test(); } private static int x; }
namespace project1 { public class Project1 { public static void test() { System.Console.Write(x); } public static void Main() { x = 1; test(); } private static int x; } }
<?php global $x; function test() { echo $x; } $x = 1; test(); ?>
def test print $x end $x = 1 test
解説
正解は「PHP」。
PHPでは、期待した「1」は出力されません。それ以外の言語では正しく「1」が出力されます。Delphi/C++/Java/C#については特にうっかりミスを起こすことはないでしょう。Rubyでは、グローバル変数を使用する場合には、変数の先頭に「$」を追加する必要があります。PHPでは、変数のスコープは関数の中と外とで異なります。そのため、以下に示すコードのように、グローバル変数を利用する場合には関数の中でもglobalの宣言が必要になります。これで期待した「1」が出力されます。
function test() { global $x; echo $x; }