programing

동적 상수 할당

powerit 2023. 6. 27. 22:35
반응형

동적 상수 할당

class MyClass
  def mymethod
    MYCONSTANT = "blah"
  end
end

오류가 나타납니다.

구문 오류: 동적 상수 할당 오류

왜 이것이 동적 상수로 간주됩니까?저는 그냥 그것에 끈을 할당하는 것입니다.

문제는 방법을 실행할 때마다 상수에 새 값을 할당한다는 것입니다.이것은 상수를 일정하지 않게 만들기 때문에 허용되지 않습니다. 문자열의 내용이 동일하더라도(현재로서는 어쨌든) 메서드가 호출될 때마다 실제 문자열 개체 자체가 다릅니다.예:

def foo
  p "bar".object_id
end

foo #=> 15779172
foo #=> 15779112

사용 사례(방법에서 상수 값을 변경하려는 이유)를 설명해 주신다면 더 나은 구현을 도와드릴 수 있을 것입니다.

클래스에 인스턴스 변수가 있는 것이 더 나을 수도 있습니다.

class MyClass
  class << self
    attr_accessor :my_constant
  end
  def my_method
    self.class.my_constant = "blah"
  end
end

p MyClass.my_constant #=> nil
MyClass.new.my_method

p MyClass.my_constant #=> "blah"

메서드에서 상수의 값을 변경하고 상수가 문자열 또는 배열인 경우 '부정행위'를 하고 다음을 사용할 수 있습니다.#replace객체를 실제로 변경하지 않고 객체가 새로운 값을 갖게 하는 방법:

class MyClass
  BAR = "blah"

  def cheat(new_bar)
    BAR.replace new_bar
  end
end

p MyClass::BAR           #=> "blah"
MyClass.new.cheat "whee"
p MyClass::BAR           #=> "whee"

Ruby의 상수는 변경할 수 없기 때문에 내부 메소드와 같이 두 번 이상 실행될 수 있는 코드 부분에 상수를 할당하는 것이 좋습니다.

일반적인 상황에서는 클래스 내부의 상수를 정의해야 합니다.

class MyClass
  MY_CONSTANT = "foo"
end

MyClass::MY_CONSTANT #=> "foo"

어떤 이유로 메서드 내에서 상수를 정의해야 하는 경우(아마도 메타프로그래밍의 경우) 다음을 사용할 수 있습니다.

class MyClass
  def my_method
    self.class.const_set(:MY_CONSTANT, "foo")
  end
end

MyClass::MY_CONSTANT
#=> NameError: uninitialized constant MyClass::MY_CONSTANT

MyClass.new.my_method
MyClass::MY_CONSTANT #=> "foo"

다시 말하지만, 그것은 정상적인 상황에서 당신이 정말로 의지해야 하는 것이 아닌가요.이러한 방식으로 상수를 할당할지 여부를 잘 모르는 경우 다음 대안 중 하나를 고려할 수 있습니다.

클래스 변수

클래스 변수는 여러 가지 방식으로 상수처럼 작동합니다.클래스의 속성이며 정의된 클래스의 하위 클래스에서 액세스할 수 있습니다.

차이점은 클래스 변수는 수정 가능하기 때문에 문제 없이 내부 메서드에 할당할 수 있다는 것입니다.

class MyClass
  def self.my_class_variable
    @@my_class_variable
  end
  def my_method
    @@my_class_variable = "foo"
  end
end
class SubClass < MyClass
end

MyClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass
SubClass.my_class_variable
#=> NameError: uninitialized class variable @@my_class_variable in MyClass

MyClass.new.my_method
MyClass.my_class_variable #=> "foo"
SubClass.my_class_variable #=> "foo"

클래스 속성

클래스 속성은 "클래스의 인스턴스 변수"의 일종입니다.값이 하위 클래스와 공유되지 않는다는 점을 제외하면 클래스 변수와 약간 유사하게 동작합니다.

class MyClass
  class << self
    attr_accessor :my_class_attribute
  end
  def my_method
    self.class.my_class_attribute = "blah"
  end
end
class SubClass < MyClass
end

MyClass.my_class_attribute #=> nil
SubClass.my_class_attribute #=> nil

MyClass.new.my_method
MyClass.my_class_attribute #=> "blah"
SubClass.my_class_attribute #=> nil

SubClass.new.my_method
SubClass.my_class_attribute #=> "blah"

인스턴스 변수

그리고 완전성을 위해 언급해야 할 것이 있습니다. 클래스가 인스턴스화된 후에만 결정될 수 있는 값을 할당해야 한다면, 일반적인 오래된 인스턴스 변수를 실제로 찾을 가능성이 높습니다.

class MyClass
  attr_accessor :instance_variable
  def my_method
    @instance_variable = "blah"
  end
end

my_object = MyClass.new
my_object.instance_variable #=> nil
my_object.my_method
my_object.instance_variable #=> "blah"

MyClass.new.instance_variable #=> nil

Ruby에서 이름이 대문자로 시작하는 변수는 상수이며 한 번만 할당할 수 있습니다.다음 대안 중 하나를 선택합니다.

class MyClass
  MYCONSTANT = "blah"

  def mymethod
    MYCONSTANT
  end
end

class MyClass
  def mymethod
    my_constant = "blah"
  end
end

루비의 상수는 메서드 내에서 정의할 수 없습니다.이 페이지 하단의 참고 사항을 참조하십시오. 예:

대문자로 변수의 이름을 지정할 수 없습니다. 그렇지 않으면 Ruby가 상수를 가정하고 값을 상수로 유지하려고 합니다. 이 경우 값을 변경하면 "동적 상수 할당 오류"가 됩니다.소문자로 하면 됩니다.

class MyClass
  def mymethod
    myconstant = "blah"
  end
end

Ruby는 재할당의 위험이 있기 때문에 메서드 내부에 상수를 할당하는 것을 좋아하지 않습니다.앞에 나온 몇 가지 SO 답변은 메소드 외부에서 할당하는 대신 클래스에서 할당하는 것이 더 나은 방법입니다.

"어레이 또는 해시의 내용을 대체할 수 있는" 배열(및 해시) 방법 #replace에 대해 상기시켜 준 Dorian과 Phrogz에게 감사드립니다.

CONSTANT의 값이 변경될 수 있지만 짜증나는 경고와 함께 변경될 수 있다는 개념은 루비의 몇 가지 개념적 실수 중 하나입니다. 이것들은 완전히 불변이거나 상수 아이디어를 완전히 버려야 합니다.코더의 관점에서 상수는 선언적이고 의도적이며 "이 값은 일단 선언/할당되면 정말로 변경할 수 없다"는 신호입니다.

그러나 때때로 "명백한 선언"은 실제로 다른 미래의 유용한 기회를 배제합니다.예를 들면...

예를 들어, REP와 같은 프롬프트 루프에서 ARGV를 다시 로드한 다음 더 많은 (후속적인) OptionParser.parse! 호출을 통해 ARGV를 다시 실행하는 등 "상수" 값을 실제로 변경해야 할 수 있는 합법적인 사용 사례가 있습니다. --voila!"명령줄 인수"에 완전히 새로운 동적 유틸리티를 제공합니다.

실질적인 문제는 "ARGV는 상수여야 한다"는 가정이나 후속 처리를 위해 var@default_argv 인스턴스에 ARGV를 할당하는 optparse 자체 초기화 방법입니다. 해당하는 경우 ARGV(ARGV)는 정말로 매개 변수가 되어 재사용을 장려해야 합니다.적절한 기본값(예: ARGV)을 사용하여 적절한 매개변수화를 수행하면 "일정한" ARGV를 변경할 필요가 없습니다.그냥 2조분의 1정도의 생각...

언급URL : https://stackoverflow.com/questions/6712298/dynamic-constant-assignment

반응형