Ruby 问一个有关 ruby 作用域的问题

edison · 2012年11月09日 · 最后由 ywjno 回复于 2012年11月12日 · 2987 次阅读
class Soap

  def inner_invoke1 (other=self)
    other.pub
    other.pro
    other.pri
  end

  def inner_invoke2
    pub
    pro
    pri
  end

  public
  def pub
    puts "public"
  end

  protected
  def pro
    puts "protected"
  end

  private
  def pri
    puts "private"
  end

end

s1=Soap.new
s1.inner_invoke1 Soap.new         #a
s1.inner_invoke1                  #b
s1.inner_invoke2                  #c

这个作用域的问题我有点看不懂了,当 inner_invoke1 不传参数的时候,为啥会报错呢?

inner_invoke1 不传参数 和 inner_invoke2 有何区别?

请先学习排代码吧

#1 楼 @chenge 好吧,现在这样如何了呢,不知道你指的是不是这些

invoke1 都会错吧。那个 other 似乎不能访问 private 的。

NoMethodError: private method 'pri' called for #<Soap:0x0000000218b828>

报错的原因是传参数 other 就是你传进去的 Soap 实例,不传就是 s1, 同样是 Soap 实例。而实例变量是无法调用 private 方法的。

#3 楼 @chenge a 会错我懂,b 也会错我不太明白,b 和 c 有何区别,为什么 c 不会错?

#4 楼 @LarryLv

报错的原因是传参数 other 就是你传进去的 Soap 实例,不传就是 s1, 同样是 Soap 实例。而实例变量是无法调用 private 方法的。

这句话我明白了,那么,最后一行代码(c)调用 inner_invoke2 的时候,里面 3 个方法都是谁在调用,难道不是 self?如果是 self 的话,那又和 b 有什么区别?

而实例变量是无法调用 private 方法的

other=self 只是说默认传入自身作为参数,但是 other 在这里是一个变量,不是 self

other=self, other is other.

b 参数提送了默认值,没传去参数时,默认就是 self 了,而 self 是什么,打印出来就知道了,我想应该就是指 s1 这个实例吧,至于 c 我觉得私有方法本来就用在自己类中吧

#5 楼 @edison 这是一个关于 ruby 私有方法的常见误解,即使是自己的 private 方法,也不能用self.priv_some_method来调用,私有方法只有一个调用方式,就是直接写

$ irb
1.9.3p286 :001 > class A
1.9.3p286 :002?>   def a; x; end
1.9.3p286 :003?>   def b; self.x; end
1.9.3p286 :004?>   private
1.9.3p286 :005?>   def x; puts 'x'; end
1.9.3p286 :006?>   end
 => nil 
1.9.3p286 :007 > sample = A.new
 => #<A:0x00000001ea16d0> 
1.9.3p286 :008 > sample.a
x
 => nil 
1.9.3p286 :009 > sample.b
NoMethodError: private method `x' called for #<A:0x00000001ea16d0>
    from (irb):3:in `b'
    from (irb):9
    from /home/john/.rvm/rubies/ruby-1.9.3-p286/bin/irb:16:in `<main>'

#10 楼 @fsword got it. thanks for your prefect reply

ruby元编程这本书的第一天里面就有讲这个private rule,可以去看看

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