代码之家  ›  专栏  ›  技术社区  ›  Dafydd Rees

如果ruby中的变量“p”没有显式定义,它的值从哪里来?

  •  4
  • Dafydd Rees  · 技术社区  · 15 年前

    问题:你在哪里 p 从下面得到它的值,为什么会发生?

    考虑irb会议:

    me@somewhere:~$ irb
    irb(main):001:0> a
    NameError: undefined local variable or method `a' for main:Object
        from (irb):1
    irb(main):002:0> foo
    NameError: undefined local variable or method `foo' for main:Object
        from (irb):2
    irb(main):003:0> p
    => nil
    irb(main):004:0> p.class
    => NilClass
    irb(main):005:0>
    

    我从来没有定义过 -那么为什么它的价值为零呢?都不是 a foo 被认出来了有什么特别的 ? 我也没有发现下面列出的任何东西 Kernel#p

    我在读所谓的 "28 bytes of ruby joy" 假设 p def p.method_missing *_ ...

    3 回复  |  直到 15 年前
        1
  •  7
  •   John Feminella    15 年前

    p 只是一种方法 Kernel 哪个电话 inspect 在它的论点上,产生人类可读的对象表示。如果你不给它任何理由,它就不会打印任何东西。不管你通过什么,它都会回来 nil . 看到了吗 Kernel#p Object#inspect .

    电源提示: 在Ruby1.9中,当您有一个方法而不知道它来自何处时,请使用 method 方法:

    ruby-1.9.1-p378 > method(:p)
     => #<Method: Object(Kernel)#p>
    

    把它一步一步地放在一起,我们把它解读为:

     p                            # We found a method called p.
     #p                           # It's an instance method.
     Object ... #p                # It's available on Object.
     Object(Kernel)#p             # It came from the Kernel module.
    

    更新: OP提供了一些来自 this article ,作者声称如果你增加一个 method_missing

    def p.method_missing*_;p;end
    

    这段有些模糊的代码应该被理解为:

    • 定义新方法( def ),调用 . 这将覆盖默认值 上的处理程序 Object ,这只会引发 NoMethodError
    • 这个方法将存在于一个叫做 p
    • 它接受任意数量的参数( * )并将它们存储在一个名为 _ .
    • 这些论据的结果叫做 .

    def p.method_missing 指两件事之一,取决于上下文:

    • 在这里的范围内。
    • p 它在作用域中,不传递任何参数。

    def p.method\u丢失 ,我们的意思是,“这个方法是在对象上定义的,对象是调用 p NilClass ; 如果你打电话 p 没有争论,你会得到 NilClass公司

    注: 反对 定义 . 为了节省几行代码而使用这种策略既愚蠢又危险,因为它会改变 . 别这样!

        2
  •  2
  •   sepp2k    15 年前

    p 是一种打印 inspect

    Kernel#p ,不是 Kernel::p

        3
  •  2
  •   cytzol    15 年前

    p 是一种 Kernel 模块。它有利于调试-它通过调用 inspect nil .

    irb(main):001:0> p 11
    11
    => 11
    irb(main):002:0> Kernel::p [1,2] + [3,4]
    [1, 2, 3, 4]
    => [1, 2, 3, 4]
    

    结果在这里打印两次,因为它还返回对象,然后irb也打印出来。

    推荐文章