【问题标题】:Why does this example treat methods as variables or constants?为什么此示例将方法视为变量或常量?
【发布时间】:2012-07-15 05:37:56
【问题描述】:

我一直在查看一些 ruby​​ 代码,并注意到有些人将方法视为变量或常量。

class Test

   def welcome_message
      "Hello World"
   end

   def greet_user
      p welcome_message
   end
end

然后你可能会编写一个继承自这个 Test 类的新类,但要改变它的行为方式。

class New_Test < Test

   # changing the welcome message
   def welcome_message
      "Greetings"
   end
end

什么时候适合做这样的事情?它似乎允许您编写更灵活的代码,因为我可以在返回值之前执行更复杂的计算,但是我无法想出一种方法来证明编写像上面两个 Test 类这样的一段代码是合理的。

【问题讨论】:

    标签: ruby variables methods constants


    【解决方案1】:

    为什么会起作用

    在 Ruby 中,每个方法都会返回一个值。在您给定的p welcome_message 示例中,您要求Ruby 打印#welcome_message 返回值的字符串表示形式。 (从技术上讲,它是将 object.inspect 写入标准输出,但这里的含义相同。)

    如果“Hello World”是字符串以外的其他对象,结果仍然是相似的。例如,如果 #welcome_method 返回一个 Fixnum 而不是一个字符串,它仍然会显示正在打印一个字符串。

    返回值

    您可以将消息存储在类或实例变量中,或者在对象上使用 getter 或 setter 方法。但是,有时直接在表达式中使用返回值比使用变量进行中间存储更方便。

    而不是像这样存储然后取消引用一个变量:

    def welcome_message
      @message = "Hello World"
    end
    
    def greet_user
      p @message
    end
    
    welcome_message # store the variable
    greet_user      # dereference then print the variable
    

    您可以直接使用#welcome_message 的返回值。

    在像原始问题中那样的人为示例中,这不太重要,但它可以在更大的应用程序中节省时间、精力或内存。即使不是,中间变量也可能成为错误或程序员错误的来源,而且直接使用这些值通常在语义上更清晰

    虽然这不适用于您的有限示例,但使用对象的公共接口来请求信息也是一种更好的做法。在这种情况下,返回值的方法是必不可少的。

    Ruby 不是一种正交语言;通常有不止一种有效的方法来做某事。最后,它是关于您试图在代码中表达的语义。

    【讨论】:

      【解决方案2】:

      方法是方法,不是变量或常量。

         def greet_user
            p welcome_message
         end
      

      因为()可以省略,所以和下面的一样。

         def greet_user
            p welcome_message()
         end
      

         def welcome_message
            "Greetings"
         end
      

      因为return可以省略,所以和下面的一样。

         def welcome_message
            return "Greetings"
         end
      

      【讨论】:

        【解决方案3】:

        当你想要一个类实例的公共常量值时,你会怎么做?你可以这样做...

        def initialize
          @welcome_message = "Greetings"
        end
        attr_reader :welcome_message
        

        但这声明了一个实例变量,这似乎不合适,因为它的值永远不会改变,并且对于所有实例都是相同的。

        WELCOME_MESSAGE = "Greetings"
        def welcome_message
          self.class::WELCOME_MESSAGE
        end
        

        这似乎更合适......但它不是有点傻吗?我们声明了一个常量,但它实际上只会在welcome_message 中使用。不需要其他任何东西来使用丑陋的self.class::WELCOME_MESSAGE。为什么不直接砍掉中间人?因此:

        def welcome_message
          "Greetings"
        end
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-05
          相关资源
          最近更新 更多