代码之家  ›  专栏  ›  技术社区  ›  AlbertMunichMar

在Ruby中,应用方法puts的对象是哪个?

  •  1
  • AlbertMunichMar  · 技术社区  · 7 年前

    在ruby中,您使用点来调用方法,或者换句话说,将方法发送到所处理的对象。

    "100".to_i
    

    我们正在将消息发送到对象“100”上

    当我们这样做时:

    puts "hello"
    

    方法puts,应用于哪个对象?

    我想:

    self.puts "hello"
    

    self是主要的,比如现在的环境,比如irb控制台。

    但它抛出了一个错误。

    Traceback (most recent call last):
            2: from /Users/albert/.rbenv/versions/2.5.0/bin/irb:11:in `<main>'
            1: from (irb):17
    NoMethodError (private method `puts' called for main:Object)
    

    更新: Ruby 2.7允许使用self调用私有方法。此功能是在上请求和讨论的 1 和 2 .

    3 回复  |  直到 5 年前
        1
  •  5
  •   Schwern    7 年前

    puts 是一个模块化的方法 Kernel 包括在 Object puts "foo" 和 Kernel.puts "foo" Kernel.puts 是显式的,而 放 可以调用本地定义的 方法

    def puts(str)
      p "my puts: #{str}"
    end
    
    puts "foo";        # "my puts: foo"
    Kernel.puts "foo"  # foo
    

    在引擎盖下, Kernel.puts 电话 $stdout.puts . $stdout IO .

        2
  •  3
  •   sawa    7 年前

    OP正确地认为,当省略显式接收器时,接收器变为 self . 自从 puts 如果没有明确的接受者也能工作,那么尝试一下也没那么糟糕 self.puts "hello" 在相同的环境中。的确 放 定义在 main ,或任何物体 自己 指向给定环境中的。

    这里的问题是,可以用显式接收器调用的方法是 平民的 方法,而 是一个 私有的 方法,该方法拒绝显式接收器。

    绕开此限制的标准方法是使用 send

    self.send(:puts, "hello")
    
        3
  •  0
  •   Jörg W Mittag    7 年前

    在Ruby中,当您省略消息发送的接收者时,隐式接收者是 总是 self

    那么说

    foo
    

    哪里 foo 不是当前词法范围中的局部变量,是吗 相当于

    self.foo
    

    private 和 self.foo 在消息发送的接收者方面是等价的,在访问控制方面可能存在差异。特别是,如果 福 是 私有的 然后 福 将工作,但 将 raise A. NoMethodError 消息异常(例如) NoMethodError (private method `foo' called for main:Object)

    所以,你一直都是对的:

    puts
    

    相当于

    self.puts
    

    但是您误读了错误消息:不是方法不存在,而是方法不存在 私有的 .

    Kernel 私有的 方法。这还包括以下方法: Kernel#print , Kernel#require 等

    推荐文章