新手问题 在类中调用以=结尾的方法的疑惑

yuhaidonghd · 2013年10月24日 · 最后由 yuhaidonghd 回复于 2013年10月25日 · 2143 次阅读
class Foo
  attr_accessor :x, :y

  def xx(a)
    @x = a
  end

  def yy(b)
    @y = b
  end

  def foo(a, b)
    xx a
    yy b
  end

  def xx=(a)
    @x = a
  end

  def yy=(b)
    @y = b
  end

  def foo_assign(a, b)
    xx=(a)
    yy=(b)
  end

  def foo=(a, b)
    foo_assign a, b
  end

  def inspect
    "#<Foo:@x=#@x,@y=#@y>"
  end
end

f = Foo.new
f.foo_assign 1, 2
p f 
# => #<Foo:@x=,@y=>
f.foo 1, 2
p f
# => #<Foo:@x=1,@y=2>
f.foo=(1, 2) # SyntaxError
f.foo= 1, 2  # ArgumentError

在 Foo#foo_assign 中貌似 xx 和 yy 被当成新定义的局部变量。是不是只能通过 self.xx=这样的显式调用才行?哪位明白人给讲讲 Ruby 对 = 的特殊处理。 写这个的时候发现 foo_assign 不能定义成 foo=,要不然 f.foo=(1, 2) 抛出异常,而且有括号和没括号还不一样。

ruby parser 的问题吧?

楼主啊,首先self.xx=是必须要写的 否则将识别成xx = a,意思是创建一个名为 xx 的 local variable,赋值为 a,不好意思,人家不看你括号或者空格的。 然后 Ruby 赋值运算只认一个参数的,这个也是语法决定的。所以即使你传两个参数,Ruby 也认为你只传入一个参数,又看到声明的时候你声明了两个参数,所以就 ArgumentError 了。 这里有个特殊的地方请注意

def f= a
  @a = a
end

self.f = 1, 2

这句语句合法,因为1, 2在赋值语句中可以为解释为一个数组,等同于[1, 2],方括号可以省略,但f=声明两个参数确实不予承认。 f.foo=(1,2)没有这个语法。1, 2旁边加一对括号,Ruby 解释器是不认识这个写法的。

#2 楼 @iBachue #1 楼 @yfractal 看来只能认为这是 Parser 的问题了,反正实际中不有有这样的写法。感谢你们的回答。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册