Разница между @instance_variable и attr_accessor

Когда вы определяете шаблон Scala, он привязывается по умолчанию (= требуется полное совпадение строк), в то время как ваша Java sj.find() ищет соответствие в любом месте внутри строки. Добавьте .unanchored для регулярного выражения Scala, чтобы также разрешить частичные совпадения:

val statePattern = statePatternString.r.unanchored
                                       ^^^^^^^^^^^

См. Демонстрация IDEONE

Некоторая ссылка UnanchoredRegex :

def unanchored: UnanchoredRegex

Создайте новое Regex с тем же шаблоном, но не нужно, чтобы целая строка соответствовала в экстракторе шаблоны.

Обычно совпадение по дате ведет себя так, как если бы шаблон был заключен в якоря, ^pattern$.

Неучтенное Regex ведет себя так, как будто эти якоря были удалены.

Обратите внимание, что этот метод фактически не лишает никаких шаблонов шаблона.

blockquote>

ANTERNATIVE SOLUTION означало бы добавление .* на конец шаблона, но помните, что точка не по умолчанию соответствует новой строке. Если решение должно быть общим, модификатор (?s) DOTALL должен быть указан в начале шаблона, чтобы убедиться, что вся строка с потенциальными последовательностями новой строки согласована.

29
задан Community 23 May 2017 в 12:34
поделиться

6 ответов

Переменная экземпляра не видна за пределами объекта, в котором она находится; но когда вы создаете attr_accessor, он создает переменную экземпляра, а также делает ее видимой (и редактируемой) вне объекта.

Пример с переменной экземпляра (не attr_accessor)

class MyClass
  def initialize
    @greeting = "hello"
  end
end

m = MyClass.new
m.greeting #results in the following error:
  #NoMethodError: undefined method `greeting' for #<MyClass:0x007f9e5109c058 @greeting="hello">

Пример с использованием attr_accessor:

class MyClass
  attr_accessor :greeting

  def initialize
    @greeting = "hello"
  end
end

m2 = MyClass.new
m2.greeting = "bonjour" # <-- set the @greeting variable from outside the object
m2.greeting #=> "bonjour"   <-- didn't blow up as attr_accessor makes the variable accessible from outside the object

Надежда, которая проясняет ситуацию.

51
ответ дан Nat Ritmeyer 23 May 2017 в 12:34
поделиться

Переменные экземпляра не видны за пределами класса.

class MyClass
  def initialize
    @message = "Hello"
  end
end

msg = MyClass.new
@message
#==> nil   # This @message belongs to the global object, not msg
msg.message
#==> NoMethodError: undefined method `message'
msg.@message
#==> SyntaxError: syntax error, unexpected tIVAR

Теперь вы всегда можете сделать это:

msg.instance_eval { @message }

Но это неловко и обманчиво. Изучение чужого класса может быть познавательным, но ваш клиентский код не должен этого делать, если вы хотите получить надежные результаты. С другой стороны, если вы хотите, чтобы клиенты могли видеть эти значения, не заставляйте их использовать instance_eval; вместо этого определите метод, который выполняет свою задачу:

class MyClass
  def message 
    return @message
  end
end
msg.message
# ==> "Hello"

Поскольку вы так часто хотите это делать, Ruby предоставляет ярлык, чтобы сделать его проще. Код ниже имеет тот же результат, что и код выше:

class MyClass
  attr_reader :message
end

Это не новый тип переменной; это просто сокращенный способ определения метода. Вы можете посмотреть на msg.methods и увидеть, что теперь у него есть метод message.

А что если вы хотите, чтобы посторонние лица не только видели значение переменной экземпляра, но и меняли его? Для этого вам нужно определить другой метод для назначения, с = в имени:

class MyClass
  def message=(new_value)
    @message = new_value
  end
end
msg.message = "Good-bye"
msg.message
# ==> "Good-bye"

Обратите внимание, что операторы назначения здесь полумагические; хотя между msg.message и = есть пробел, Ruby все еще знает, как вызвать метод message=. Комбинированные операторы, такие как += и т. Д., Также инициируют вызовы метода.

Опять же, это общий дизайн, поэтому Ruby также предоставляет для него ярлык:

class MyClass
  attr_writer :message
end

Теперь, если вы используете attr_writer самостоятельно, вы получите атрибут, который можно изменить, но не видел. Есть некоторые странные случаи использования, когда это то, что вам нужно, но в большинстве случаев, если вы собираетесь позволить посторонним изменять эту переменную, вы также хотите, чтобы они тоже могли ее прочитать. Вместо того, чтобы объявлять оба attr_reader и attr_writer, вы можете объявить оба сразу так:

class MyClass
  attr_accessor :message
end

Опять же, это всего лишь ярлык для определения методов, которые позволяют вам получить переменная экземпляра вне класса.

27
ответ дан Mark Reed 23 May 2017 в 12:34
поделиться

Поскольку attr_accessor определяет методы, вы можете вызывать их извне класса. A @variable доступен только из класса.

1
ответ дан jleeothon 23 May 2017 в 12:34
поделиться

В OOPS у нас есть понятие, называемое инкапсуляция , которое означает, , что внутреннее представление объекта обычно скрыто от взгляда вне определения объекта. Только сам объект может возиться со своим внутренним состоянием. Внешний мир не может.

Каждый объект обычно определяется его состоянием и поведением , в ruby ​​переменные экземпляра называются внутренним состоянием или состоянием объекта, и согласно OOPS состояние не должно быть доступно любому другому объекту и выполнению поэтому мы придерживаемся инкапсуляции.

ex: class Foo def initialize(bar) @bar = bar end end

Выше мы определили класс Foo и в методе initialize мы инициализировали переменную экземпляра (атрибут) или (свойство). когда мы создаем новый объект ruby, используя новый метод, который, в свою очередь, вызывает метод инициализации внутри, когда метод запускается, переменная экземпляра @bar объявляется и инициализируется, и она будет сохранена как состояние объекта.

Каждая переменная экземпляра имеет свое собственное внутреннее состояние и уникальна для самого объекта, каждый метод, который мы определяем в классе, будет изменять внутреннее состояние объекта в соответствии с определением и целью метода. здесь метод initialize делает то же самое, например, создает новую переменную экземпляра.

var object = Foo.new(1)
#<Foo:0x00000001910cc0 @bar=1>

В фоновом режиме ruby ​​создал переменную экземпляра (@bar = 1) и сохранил значение как состояние объекта внутри объекта «объект». мы можем проверить это с помощью метода instance_variables, и эти методы возвращают массив, содержащий все переменные экземпляра объекта в соответствии с текущим состоянием объекта.

object.instance_variables
#[
     [0]: @bar
 ]

мы можем видеть переменную экземпляра '@bar' выше. который создается, когда мы вызываем метод initialize объекта. эта переменная @bar не должна быть видимой (скрытой) по умолчанию, и поэтому ее не могут видеть другие снаружи объекта, кроме объекта, изнутри. Но объект может возиться со своим собственным внутренним состоянием, и это означает, что он может показать или изменить значения, если мы дадим ему способ сделать это, эти два можно сделать, создав новые методы экземпляра в классе.

когда мы хотим увидеть переменную @bar, вызвав ее, мы получаем ошибку, так как по умолчанию мы не можем видеть состояние объекта.

show = object.bar
#NoMethodError: undefined method `bar' for #<Foo:0x00000001910cc0 @bar=1>
#from (irb):24
#from /home/.rvm/rubies/ruby-2.0.0-p648/bin/irb:12:in `<main>'

Но мы можем получить доступ к переменным двумя методами, эти два называются методами setter и getter , которые позволяют объекту отображать или изменять свое внутреннее состояние (переменные экземпляра / атрибуты / свойства) соответственно.

class Foo
  def bar
    @bar
  end

  def bar=(new_bar)
    @bar = new_bar
  end
end

Мы определили методы getter (bar) и setter (bar =), мы можем назвать их любым способом, но переменная экземпляра внутри должна совпадать с переменной экземпляра, которой мы хотим показать или изменить значение. сеттеры и геттеры в некотором смысле являются нарушением концепций OOPS, но они также являются очень мощными методами.

Когда мы определяем два метода путем повторного открытия класса и определения их, когда мы вызываем объект с помощью методов, мы можем иметь возможность просматривать переменные экземпляра (здесь @foo) и также изменять его значение.

object.bar
1

object.bar=2
2

object.bar
2

Здесь мы вызвали метод bar (getter), который возвращает значение @bar, а затем мы назвали bar = метод (setter), который мы указали в качестве аргумента new_value, и он изменил значение переменной экземпляра ( @bar) и мы можем посмотреть его снова, вызвав метод bar.

В ruby ​​у нас есть метод с именем attr_accessor , который объединяет как методы-установщики, так и методы-получатели, мы определяем его выше определений методов внутри класса. Методы attr_ * являются ярлыком для создания методов (setter и getter)

class Foo
  attr_accessor :bar
end

мы должны предоставить символ (: bar) в качестве аргумента метода attr_accessor, который создает методы как setter, так и getter внутренне с именами методов как указано имя символа.

Если нам нужен только метод получения, мы можем вызвать attr_reader: bar. Если нам нужен только метод установки, мы можем вызвать attr_writer: bar

attr_accessor создает методы как attr_writer, так и attr_reader

мы можем предоставить столько переменных экземпляра, сколько мы хотим, методам attr_ *, разделенным запятыми

class Foo
  attr_writer :bar
  attr_reader :bar
  attr_accessor :bar, :baz
end
2
ответ дан Ashok Allu 23 May 2017 в 12:34
поделиться

attr_accesor предоставляет вам методы для чтения и записи переменных экземпляра. Переменные экземпляра предназначены для сокрытия от внешнего мира, поэтому для связи с ними необходимо иметь методы attr _ibute accesor .

8
ответ дан megas 23 May 2017 в 12:34
поделиться

И еще один ответ, более компактный (для разработчиков Java) attr_accessor :x создает геттеры и сеттеры, чтобы @x

class MyClassA
  attr_accessor :x
end

был такой же, как

class MyClassB
  def x=(value) #java's typical setX(..)
    @x=value
  end
  def x
    @x
  end
end
0
ответ дан estani 23 May 2017 в 12:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: