新手问题 Ruby 里面如何区分方法和本地变量的

qqren · 发布于 2017年5月15日 · 最后由 lithium4010 回复于 2017年5月21日 · 543 次阅读
96

color = :red 和 self.color = :orange,为什么第一个是本地变量赋值,而第二个是方法调用? 为什么第一个不是隐含的 对self调用color=()方法呢?

class TrafficLight
  attr_accessor :color

  def progress_color
    case color
    when :orange
      #Don't do this!
      color = :red
    when :green
      #Do this instead!
      self.color = :orange
    else
      raise NotImplementedError, "What should be done if color is already :red? Check with the domain expert, and build a unit test"
    end
  end
end

traffic_light = TrafficLight.new
traffic_light.color = :green
traffic_light.progress_color
traffic_light.color # Now orange
traffic_light.progress_color
traffic_light.color # Still orangea
共收到 9 条回复
96

http://stackoverflow.com/questions/44715/why-do-ruby-setters-need-self-qualification-within-the-class

找到一个合理的说法,就是如果不使用 self.attr= 来显式的调用attr=()方法的话,就没办法实现在方法内部定义本地变量的功能了,因为按照ruby的方法寻找,最后会到method_missing。抛出异常。

4375

在 Ruby 里面,local variable 和 setter method 还是挺容易区分的。前者就是一个赋值过程,左值是一个变量。而后者是一个 send message 的过程+包装了一层语法糖,self.color = :orange 实际上等同于 self.send('color=', :orange) ,意思是向 self 对象发送一个消息 color= 的信号,参数为 :orange

1

color = :red 隐含调用方法不就没办法设局部变量了?

12700

Java写多了?

20859

要是你定义的局部变量和方法名称重名,同样局部变量的优先级也更高。

E5a8ce

在类内部调用实例变量时,我一般都是用 @color 这种方式的

15139

变量只有本地。对象加点后面跟的一定是方法。

Ruby 是一门面向对象的语言,对象之间操作全部使用消息传递。

a.x 是向 a 对象发送 :x 消息,这里的x自然不是变量而是消息内容了。

同理 a.x= 是发送 :'x=' 消息。

然后如果让 x = 1 也变成向 self 发消息的话,就没法写入本地变量了。

43079a

这应该就是‘@’存在的意义吧,正如6楼所讲

8744
E5a8cewinse 回复

感觉用attr_accessor调用更好写测试

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