【问题标题】:In Ruby, inside a class method, is self the class or an instance?在 Ruby 中,在类方法中,self 是类还是实例?
【发布时间】:2011-05-19 23:09:42
【问题描述】:

我知道self 是实例方法中的实例。那么,self 是类方法内部的类吗?例如,以下内容可以在 Rails 中使用吗?

class Post < ActiveRecord::Base
  def self.cool_post
    self.find_by_name("cool")
  end
end

【问题讨论】:

  • 并添加到以下答案中,因为除非指定,否则 ruby​​ 将始终将接收器评估为 self,您的上述代码可以在没有 self 的情况下调用 find_by_name :)
  • 谢谢,在某些情况下指定self 是个好主意吗? self.find_by_name 是 Ruby 寻找find_by_name 的第一个位置吗?它看起来在其他地方吗?在全局定义的方法中(在类之外的文件中定义的方法)呢?
  • 我测试过了。似乎优先顺序是类方法,如果没有找到类方法,然后是全局定义的方法。
  • 我创建了一个显示the method lookup order in Ruby 的图表。您可能会发现它很有用。
  • 至少在 Ruby 1.9.2 中,“全局定义”方法实际上是 Object 上的私有方法。例如:def foo; end; Object.private_methods.include?(:foo) # =&gt; true。这意味着它们基本上最终位于继承链的顶部,并且是最后被找到的。

标签: ruby class instance self class-method


【解决方案1】:

没错。类方法中的self 是类本身。 (还有在类定义里面,比如def self.coolpost中的self。)

您可以使用 irb 轻松测试这些花絮:

class Foo
  def self.bar
    puts self.inspect
  end
end

Foo.bar  # => Foo

【讨论】:

    【解决方案2】:
    class Test
        def self.who_is_self
            p self
        end
    end
    
    Test.who_is_self
    

    输出:

    测试

    现在,如果您想要一个特定于 Rails 的解决方案,它被称为 named_scopes:

    class Post < ActiveRecord::Base
       named_scope :cool, :conditions => { :name => 'cool' }
    end
    

    这样使用:

    Post.cool
    

    【讨论】:

      【解决方案3】:

      简短回答:

      我喜欢对这些问题做的只是启动一个 irb 或 ./script/console 会话

      然后您可以执行以下操作以查看魔术:

      ruby-1.8.7-p174 > class TestTest
      ruby-1.8.7-p174 ?>  def self.who_am_i
      ruby-1.8.7-p174 ?>    return self
      ruby-1.8.7-p174 ?>    end
      ruby-1.8.7-p174 ?>  end
       => nil 
      ruby-1.8.7-p174 > TestTest.who_am_i
       => TestTest
      

      钓鱼愉快!

      【讨论】:

        【解决方案4】:

        已经有很多答案了,但这里是为什么 self 是类:

        点将self 更改为点之前的任何内容。因此,当您执行foo.bar 时,对于bar 方法,selffoo。类方法没有区别。调用Post.cool_post 时,您会将self 更改为Post

        这里要注意的重要一点是,决定self 的不是方法的定义方式,而是它的调用方式。这就是它起作用的原因:

        class Foo
          def self.bar
            self
          end
        end
        
        class Baz < Foo
        end
        
        Baz.bar # => Baz
        

        或者这个:

        module Foo
          def bar
            self
          end
        end
        
        class Baz
          extend Foo
        end
        
        Baz.bar # => Baz
        

        【讨论】:

          猜你喜欢
          • 2016-01-28
          • 1970-01-01
          • 1970-01-01
          • 2014-03-12
          • 1970-01-01
          • 2018-06-28
          • 2015-03-03
          • 2015-04-29
          • 1970-01-01
          相关资源
          最近更新 更多