Можно ли опустить @ при вызове переменных экземпляра

Если у вас есть класс с attr_accessor, нельзя опустить символ @ при вызове переменных экземпляра с self.instance_variable будет подразумеваться, если вы не используете символ@?

4 ответа

  1. В случае, когда у вас есть attr_accessorи вы хотите прочитать значение, вы получите то же самое значение. Это не совсем то, что вы пропускаете@, но что вы вызываете метод с тем же именем, которое возвращает переменную экземпляра.

    Пропуск @при попытке установить значение не будет работать таким же образом; он будет просто установить локальную переменную с тем же именем. Использование задатчика объекта внутри объекта требует, чтобы вы предшествовали ему self..

    class Foo
      attr_accessor :bar
    
      def getter_equivalent?
        bar.equal?(@bar) # Returns true. They are the same object.
      end
    
      def set_with_at(value)
        @bar = value  # Will set the instance variable
      end
    
      def set_without_at(value)
        bar = value  # Will not set the instance variable
      end
    
      def set_with_self(value)
        self.bar = value  # Will set the instance variable
      end
    
    end
    
  2. Пример класса с attr_accessorрасширенным для ясности. Обычный initializeметод был опущен, чтобы сосредоточиться на задаче под рукой:

    class Foo
    
      def bar
        @bar
      end
    
      def bar=(bar)
        @bar = bar
      end    
    
      #the above two methods represent attr_accessor :bar      
    
      def call_method
        bar
        #same as self.bar
        #self refers to the current object i.e. the current instance of Foo
        #bar refers to the method bar defined above
      end
    
      def call_instance_var
        @bar
        #refers directly to the the instance variable
      end
    end
    

    Вы можете использовать любой из них, я лично предпочитаю вызывать метод, а не переменную экземпляра.

    Образец

    foo = Foo.new
    foo.bar = "bar"
    foo.call_method       #=> "bar"
    foo.call_instance_var #=> "bar"
    
  3. attr_accessor :foo это в основном просто метод, который генерирует два метода (геттер и сеттер) для вашего:

    def foo
      @foo
    end
    
    def foo=(foo)
      @foo = foo
    end
    

    Можно ли опустить @при вызове переменной экземпляра? Kind of-вызов имени переменной экземпляра без @средств вызова метода экземпляра, сгенерированного attr_accesorвместо того, чтобы вызывать переменную экземпляра. Это работает до тех пор, пока метод getter не переопределен или не расширен.

    Но когда вы попытаетесь установить переменную экземпляра без@, это не будет работать таким образом. Потому что тогда Ruby установит локальную переменную с таким именем. Чтобы задать переменную экземпляра с помощью метода экземпляра, созданного, attr_accessorнеобходимо написать self.(или другой приемник) вместо @:

    @foo = 'bar'      # assigns `'bar'` to the instance variable `@foo`
    foo = 'bar'       # assigns `'bar'` to a local variable `@foo`
    

    Но использовать метод setter, сгенерированный attr_accessor:

    self.foo = 'bar'  # passes `'bar'` to `self` instance method `foo=`
    
  4. Хотя в классе можно использовать методы доступа, лучше использовать @символ для ссылки на переменные экземпляра.

    Вот пример, когда использование метода reader в классе приведет к неожиданным результатам:

    class A
    
      def var
        @var
      end
    
      def defined_using_method?
        defined?(var)
      end
    
      def defined_using_at?
        defined?(@var)
      end
    
    end
    
    A.new.defined_using_method? # => "method"
    A.new.defined_using_at? # => nil