When to use `self.foo` instead of `foo` in Ruby methods

后端 未结 3 1477
梦如初夏
梦如初夏 2020-11-27 04:22

This is not specific for Rails - I am just using Rails as an example.

I have a model in Rails:

class Item < ActiveRecord::Base

  def hello
    p         


        
相关标签:
3条回答
  • 2020-11-27 04:38
    1. It is idiomatic to prefer to omit self. when invoking methods; it is generally never needed.

    2. You must use self.foo = xxx when calling a setter method, instead of foo = xxx, so that Ruby realizes that you are not trying create a new local variable.

      • Similarly, in the unlikely event that you have an existing local variable do_something with the same name as a method, you must use self.do_something to invoke the method, as just do_something will end up reading the variable.
    3. You cannot use self.foo(...) to call a private method; you must instead call just foo(...).

    0 讨论(0)
  • 2020-11-27 04:41

    Following this tutorial, you have no need to use self pointer. But i think this (or self in our case) pointers are used to resolve name conflicts. Actually, @name and self.name are the same statements (if there is no name method for your class). E.g.:

    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'!
    

    Try running this code and you'll see =)

    0 讨论(0)
  • 2020-11-27 04:58

    If you omit self Ruby will first look for local variables with that name, then for an instance method. It's not idiomatic to write self.. In any case, you have to write self.something = value on assignations.

    Note that you cannot use self when calling private methods (no problem with protected methods):

    class A
      def foo; self.bar; end
    
    private
    
      def bar; "bar"; end
    end
    
    A.new.foo  
    # private method `bar' called for #<A:0x7f49193584f0> (NoMethodError)
    
    0 讨论(0)
提交回复
热议问题