class Example
 private
 def example_test
  puts 'Hello'
 end
end

e = Example.new
e.example_test

这当然行不通,因为我们指定了示例(e)的显式接收方实例,这违反了"私有规则".

但我不明白,为什么一个人不能在Ruby中这样做:

class Foo
 def public_m
  self.private_m # <=
 end
 private
 def private_m
  puts 'Hello'
 end
end

Foo.new.public_m

public_m方法定义(即self)中的当前对象是Foo的实例.那为什么不允许呢?为了解决这个问题,我必须将self.private_m改为private_m.但是为什么这不同呢,self不是Foo在public_m中的一个例子吗?谁是裸字private_m呼叫的接受者?这不是self吗?实际上你忽略了什么,因为Ruby会为你做这件事(会自己打电话给private_m)?

我希望我没有把它搞糊涂,我对Ruby还很 fresh .


编辑:

class Example 

 # self as an explicit receiver (will throw an error)
 def explicit 
  self.some_private_method
 end

 # self as an implicit receiver (will be ok)
 def implicit
  some_private_method
 end

 private

 def some_private_method; end
end

Example.new.implicit

给在谷歌追踪中发现这个问题的人的信息:这可能会有帮助-http://weblog.jamisbuck.org/2007/2/23/method-visibility-in-ruby

推荐答案

这里是长的和短的.在Ruby中,private的意思是不能用显式接收器调用方法,例如某个_实例.private_方法(值).因此,尽管隐式接收方是self,但在您的示例中,您显式使用self,因此无法访问私有方法.

这样想,您是否希望能够使用分配给类实例的变量调用私有方法?不,Self是一个变量,所以它必须遵循相同的规则.然而,当您只是在实例内部调用该方法时,它会按预期工作,因为您没有显式地声明接收方.

Ruby就是这样,您实际上可以使用instance_eval调用私有方法:

class Foo
  private
  def bar(value)
    puts "value = #{value}"
  end
end

f = Foo.new
begin
  f.bar("This won't work")
rescue Exception=>e
  puts "That didn't work: #{e}"
end
f.instance_eval{ bar("But this does") }

希望这更清楚一点.

--编辑--

我想你知道这会管用的:

class Foo
 def public_m
  private_m # Removed self.
 end
 private
 def private_m
  puts 'Hello'
 end
end

Foo.new.public_m

Ruby相关问答推荐

使用 Ruby,我如何访问和比较这些嵌套的数组值?

Ruby中带和不带下划线_的方法参数有什么区别

如何在 Ruby 的 RestClient gem 中设置超时?

如何使用 yardoc 列出未记录的模块/类/常量/方法?

Ruby 中 Postgres 查询的简单示例

你喜欢哪种风格的 Ruby 字符串引用?

什么时候在 Ruby 中使用 Struct 比使用 Hash 更好?

如果尚未定义,则设置 Ruby 变量

卸载所有 gem Ruby 2.0.0

如何使用 Ruby OptionParser 指定所需的switch (不是参数)?

如何在课堂上使用 Enumerable mixin?

Ruby 1.9 哈希,键中有破折号

map、each 和 collect 有什么区别?

Ruby 将 CSV 文件读取为 UTF-8 和/或将 ASCII-8Bit 编码转换为 UTF-8

从Ruby中的子类方法调用父类中的方法

使用正则表达式进行 Ruby Electron邮件验证

obj.nil?与 obj == nil

等号 ('=') 放在方法定义中的方法名称之后有什么作用?

当我们导入 csv 数据时,如何消除UTF-8 中的无效字节序列

判断文件名是文件夹还是文件