понять себя для метода класса attr_accessor - PullRequest
6 голосов
/ 11 мая 2011
class Test
  class << self
    attr_accessor :some

    def set_some
      puts self.inspect
      some = 'some_data'
    end
    def get_some
      puts self.inspect
      some
    end
  end
end

Test.set_some => Test
puts Test.get_some.inspect => Test nil

Здесь выше я могу найти себя как сам Тест, но не возвращаю some_data в качестве вывода.

Но, хотя я изменил следующим образом, он возвращает ожидаемый результат

class Test
  class << self
    attr_accessor :some

    def set_some
      puts self.inspect
      self.some = 'some_data'
    end
    def get_some
      puts self.inspect
      self.some
    end
  end
end

Test.set_some => Test
puts Test.get_some.inspect => Test some_data

В чем различия?

EDIT

Теперь в первом примере, если я выберу метод get some как

Test.some = 'new_data'
puts Test.some.inspect #=> new_data
Test.set_some
puts Test.get_some.inspect => new_data

Теперь это сильно смутило меня.

Ответы [ 5 ]

12 голосов
/ 11 мая 2011

some = :foo заставляет ruby ​​думать, что он должен создать новую локальную переменную с именем some.Если вы хотите вызвать some=(), вы должны использовать явный приемник - как в self.some = :foo.Однажды я проиграл пари ...: - /

1 голос
/ 11 мая 2011

Это (локальная) переменная в первом примере

0 голосов
/ 28 декабря 2013

Пример 1 без переопределения метода и без локальной переменной

class Foo
  def initialize
    @foo = 'foo'
  end

  def print_foo
    print @foo
    print self.foo
    print foo
  end
end

@ foo, self.foo и foo будут обращаться к переменной экземпляра @foo в методе экземпляра:

Foo.new.print_foo # => foofoofoo

Пример 2 с переопределением метода

class Foo
  def initialize
    @foo = 'foo'
  end

  def foo
    return 'bar'
  end

  def print_foo
    print @foo
    print self.foo
    print foo
  end
end

@ foo получит доступ к переменной экземпляра, но self.foo и foo вызовут метод переопределения foo:

Foo.new.print_foo # => foobarbar

Пример 3 с переопределением метода и локальной переменной

class Foo
  def initialize
    @foo = 'foo'
  end

  def foo
    return 'bar'
  end

  def print_foo
    foo = 'baz'
    print @foo
    print self.foo
    print foo
  end
end

@ foo обращается к переменной экземпляра, self.foo обращается к методу переопределения, а foo обращается к локальной переменной:

Foo.new.print_foo # => foobarbaz

0 голосов
/ 09 января 2012

в первом методе

def set_some
  puts self.inspect
  some = 'some_data'
end

some - это локальная переменная ... она не совпадает с @some, которая является переменной экземпляра (в данном случае переменной экземпляра класса), поэтому значение исчезает, когда метод заканчивается.

если вы хотите вызвать метод setter несколько или установить @some на что-то, сделайте это

@some = 'some_data'

или

self.some = 'some_data'

во втором методе

def get_some
  puts self.inspect
  self.some
end

Вы вызываете метод some. которая возвращает переменную instace @some .. и поскольку в этой точке @some не имеет значения .. возвращает nil ..

0 голосов
/ 11 мая 2011

В первом примере some является локальной переменной.

Во втором some - это метод self. Зачем? Потому что attr_accessor :some совпадает с:

def some= (val)
  @some = val
end

def some
  return @some
end

Итак, вы создали методы getter и setter для переменной экземпляра @some (это переменная экземпляра объекта Test, поскольку каждый класс также является объектом класса Class).

...