在你看来,你遇到过的最令人惊讶、最怪异、最奇怪或最“WTF”的语言特性是什么?

请每个回答只回答一个特征。


当前回答

在Perl中,可以通过修改一个类的@ISA数组来改变它的继承链,这让我很惊讶。

package Employee;
our @ISA = qw(Person);
# somwhere far far away in a package long ago
@Employee::ISA = qw(Shape); 
# Now all Employee objects no longer inherit from 'Person' but from 'Shape'

其他回答

JavaScript中的变量赋值可以创建全局变量。如果一个变量在函数中被赋值,并且没有在相同的作用域中声明为var,那么它将隐式声明为global。

function foo() {
  x = "juhu";  // creates a global variable x!
  var y = "kinners"
}

foo();
alert(x); // alerts "juhu"
alert(y); // alerts undefined

注意,var语句也可以在给变量赋值后使用:

function foo() {
  x = 12;
  var x; // x is now local
  return x;
}

alert(foo()); // will alert 12;
alert(x); // will alert undefined

其余的这些都没有令人震惊的Ruby触发器操作符:

p = proc {|a,b| a..b ? "yes" : "no" }

p[false,false]    => "no"
p[true,false]     => "yes"
p[false,false]    => "yes"   # ???
p[false,true]     => "yes"
p[false,false]    => "no"

是的,程序状态存储在解释器的解析树中。这就是为什么开发一个兼容的Ruby实现要花很长时间的原因。但是我原谅你,Ruby

在PHP中,必须显式地引用全局变量,并显式地使用这个->作为类变量。使重构变得有趣。如果不找到所有使用点,就不能将变量/参数提升为全局变量或类成员。

在统一中,

GameObject.Find("MyObject")

将正常返回对象。然而,如果你这样做:

GameObject.Find("MyObject").active = false;
//do other stuff
if (GameObject.Find("MyObject").active)
{
    //do stuff
}

然后您将得到一个空引用。在Unity iPhone中,这段代码通常在编辑器中正常工作,但在iPhone上运行时会导致SIGBUS。问题是GameObject.Find()将只定位活动对象,所以即使你只是检查它是否活动,你也会有效地调用if (null.active)。

为了使它正常工作,你必须在使它不活跃之前存储它。

GameObject obj = GameObject.Find("MyObject");
obj.active = false;
//do other stuff
if (obj.active)
{
    //do stuff
}

可以说,这是一种更好的实践,但Unity处理非活动对象的方式通常是相当奇怪的。它似乎卸载了大部分非活动对象(纹理等),但不是全部,因此非活动对象仍然会消耗大量内存。

在Python中,每个字符串都包含空字符串。

answer = input("Enter 'Y[es] or N[o]:")
if answer in 'YyNn':        # verify input
    process(answer) 

只要在上面的查询中点击return就会将答案设置为空字符串,将if答案传递给…测试,并被处理为正确答案。更简洁地说:

>>> "ABCDEFGHIJ".__contains__("")
True

像往常一样,Python在这里的行为在数学和逻辑上都是无可挑剔的。就像我在很久以前的集合论课上回忆的那样:空集合是每个集合的成员。

当我偶尔被它咬到的时候,它仍然让我感到惊讶,但我不会有其他的方式。