【问题标题】:When to use `self.foo` instead of `foo` in Ruby methods何时在 Ruby 方法中使用 `self.foo` 而不是 `foo`
【发布时间】:2023-03-22 04:25:01
【问题描述】:

这不是特定于 Rails 的——我只是以 Rails 为例。

我在 Rails 中有一个模型:

class Item < ActiveRecord::Base

  def hello
    puts "Hello, #{self.name}"
  end
end

(假设Item 模型(类)有一个名为name 的方法。)什么时候需要使用self.name,什么时候可以只使用name(例如#{name})?

【问题讨论】:

  • 这个问题也让我很头疼。

标签: ruby self


【解决方案1】:
  1. 在调用方法时喜欢省略self.是惯用的;一般不需要。

  2. 必须在调用setter 方法时使用self.foo = xxx,而不是foo = xxx,以便Ruby 意识到您不是在尝试创建新的局部变量。

      1234563变量。
  3. 不能使用self.foo(...) 调用私有方法;你必须改为只打电话给foo(...)

【讨论】:

    【解决方案2】:

    如果您省略self,Ruby 将首先查找具有该名称的局部变量,然后查找实例方法。写self. 不习惯。在任何情况下,您都必须在作业上写self.something = value

    请注意,调用私有方法时不能使用self(受保护方法没有问题):

    class A
      def foo; self.bar; end
    
    private
    
      def bar; "bar"; end
    end
    
    A.new.foo  
    # private method `bar' called for #<A:0x7f49193584f0> (NoMethodError)
    

    【讨论】:

      【解决方案3】:

      跟随this tutorial,你不需要使用self指针。但我认为 this (或我们的例子中的 self )指针用于解决名称冲突。实际上,@nameself.name 是相同的语句(如果您的类没有 name 方法)。例如:

      class Moo
        attr_accessor :name
      
        def moo(name)
          name = name # O_o which *name* should i use?
        end
      
        def foo(name)
          @name = name # the same as *self.name = name*
        end
      
        def hello
          puts self.name # the same as *puts @name*
        end
      end
      
      a = Moo.new
      a.hello() # should give no output
      
      a.moo('zaooza')
      a.hello() # Hey! Why does it prints nothing?
      
      a.foo('zaooza')
      a.hello() # whoa! This one shows 'zaooza'!
      

      尝试运行这段代码,你会看到 =)

      【讨论】:

      • 还有一种特殊情况:名为foo=的方法必须通过self.foo=调用,否则它定义了一个名为foo的新变量。
      • 是的,你是对的。抱歉,我忽略了这一点,完全忘记了运营商......
      • @nameself.name 绝对是同一个语句。 self.name 是一个方法调用,@name 是一个实例变量。只是在您的示例中(但不是在 OP 中),self.name 是一个恰好返回@name 的方法。在 OP 的示例中,self.name 将获取存储在数据库中的值,而@name 将只是nil,因此它们绝对不一样。
      • @shybovycha:不,没有更正。如果没有name 方法,self.name 将导致NoMethodErrorself.name 始终是一个方法调用。它永远不是变量(尽管它很可能返回变量的内容)。
      • sepp 是对的。同样习惯性地,我认为我以前从未见过有人在 ruby​​ 中的方法调用中使用空括号。
      猜你喜欢
      • 2016-12-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-21
      • 2012-10-17
      • 2011-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多