ruby - ==(等于)在 Ruby 1.8 中是如何工作的?

标签 ruby string

下面描述的似乎是 Ruby 1.8(和 REE)中的错误,但已在 1.9 中修复。

我想知道:

  1. 为什么打电话 ==StringFixnum触发调用 ==other反对吗?
  2. 为什么打电话 ==String根据 other 的不同工作方式不同对象类?

现在是代码:

class A
  def ==(other)
    puts "In A: calling == against #{other}"
    super
  end
end

class E < Exception
  def ==(other)
    puts "In E: calling == against #{other}"
    super
  end
end

示例 1

"foo" == A.new
=> false

这里没什么有趣的,继续。

例子2

"foo" == E.new
In E: calling == against foo
=> false

调用 ==String触发器 ==other Exception 的对象类。

示例 3

42 == A.new
In A: calling == against 42
=> false

调用 ==Fixnum触发器 ==other对象。

例子4

42 == E.new
In E: calling == against 42
=> false

调用 ==String触发器 ==other Exception 的对象类。

最佳答案

这似乎仅适用于某些类型 - 在本例中为 Fixnums。我无法复制您的示例 #2(编辑:我复制了,见底部),但示例 3 和 4 很容易复制。

因此,查看 numeric.c,我们看到 Ruby 在 y(第二个参数)上调用 equal?,而不是 x

static VALUE
num_equal(x, y)
    VALUE x, y;
{
    if (x == y) return Qtrue;
    return rb_funcall(y, id_eq, 1, x);
}

看看这个例子:

1.8.7 :001 > class Foo
1.8.7 :002?>   def ==(other)
1.8.7 :003?>     puts "In foo"
1.8.7 :004?>     super
1.8.7 :005?>     end
1.8.7 :006?>   end
 => nil
1.8.7 :007 > 42 == Foo.new
In foo
 => false
1.8.7 :008 > Foo.new == 42
In foo
 => false
1.8.7 :009 > Foo.new == Foo.new
In foo
 => false
1.8.7 :010 > "" == Foo.new
 => false

在 #7 中,我们将 42 (x) 与 Foo.new (y) 进行比较。这将调用 y.==(x),它将调用 Foo#==

在 #8 中,我们将其反转;这里没有什么有趣的东西,我们只是调用 Foo#== 并且它的行为符合预期。

但是,在 #9 中,比较 Foo 的两个实例只会导致一次调用 Foo#==== 不在参数上调用,只在接收者上调用。

#10 根本不调用 Foo#==

交换比较是 Ruby 的数字类型实现 == 的一个怪癖,而不是 Ruby 的相等运算符本身的特定属性。

编辑:字符串有同样的事情发生。

static VALUE
rb_str_equal(str1, str2)
    VALUE str1, str2;
{
    if (str1 == str2) return Qtrue;
    if (TYPE(str2) != T_STRING) {
      if (!rb_respond_to(str2, rb_intern("to_str"))) {
        return Qfalse;
      }
      return rb_equal(str2, str1);
    }
    if (RSTRING(str1)->len == RSTRING(str2)->len &&
      rb_str_cmp(str1, str2) == 0) {
      return Qtrue;
    }
    return Qfalse;
}

它首先用第二个参数调用rb_equal。它不调用 Foo#== 的原因是我示例中的 Foo 没有实现 #to_str,所以它只是返回错误的。但是,Exception 实现了 #to_str,因此它的一个子类会传递给示例中的 rb_equal 测试。

关于ruby - ==(等于)在 Ruby 1.8 中是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16994398/

相关文章:

ruby - 哪些 Ruby 库支持 Relax NG 紧凑语法验证?

ruby-on-rails - 从 Rails : dependency issues 调用外部 rake 任务

r - 在 R 中存储长字符串(DNA 序列)

java - Google map 查询返回的 JSON 包含像\x26 这样的编码字符(如何解码?)

javascript - 如果字符串不是较大字符串的一部分,则使用 javascript 中的正则表达式替换字符串

java - 更严格的 String.format 不会忽略额外的参数?

ruby - 如何使用 Gnuplot 创建多页 PDF 文件?

mysql - 未定义方法 `eq' 为 nil :NilClass with rails 3 and ruby enterprise on ubuntu hardy

ruby - 在 Ruby 中,coerce() 是如何工作的?

excel - 与字符串比较时如何使用 "TypeOf ___ is ___ Then "