Ruby에서 상수란 무엇입니까?
상수는 항상 대문자로 시작하는 변수 유형입니다. 외부에서만 정의할 수 있습니다. 메타프로그래밍을 사용하지 않는 한.
상수는 변경되지 않아야 하는 값에 사용되지만 Ruby는 변경을 방지하지 않습니다.
이렇게 생겼어요 :
FRUIT = "orange"
지금 :
상수는 중요한 주제이기 때문에 이 기사에서 자세히 살펴보겠습니다!
상수 정의 방법
상수는 선언하는 데 특별한 기호나 구문이 필요하지 않습니다. 첫 글자를 대문자로 만들기만 하면 됩니다.
다음은 유효한 상수입니다. :
ABC = 1 Goo = 2 Foo = 3
메서드 내에서 상수를 정의할 수 없다는 점에 유의하십시오.
이 수수께끼 같은 오류 메시지가 표시됩니다. :
def the_method ABC = 1 end # "dynamic constant assignment"
따라서 메서드 외부에서 상수를 정의하기만 하면 됩니다. 일반적으로 클래스 상단에 상수 정의를 두어 명확하게 볼 수 있기를 원합니다.
class RubyBlog URL = "rubyguides.com" AUTHOR = "Jesus Castello" end
그런 다음 다음 구문을 사용하여 클래스 메서드 내부 또는 클래스 외부에서 이러한 상수에 액세스할 수 있습니다.
p RubyBlog::AUTHOR # "Jesus Castello"
이 게시물의 뒷부분에서 상수의 범위에 대해 조금 더 이야기할 예정이므로 계속 지켜봐 주시기 바랍니다!
초기화되지 않은 상수 오류
발생할 수 있는 일반적인 오류 중 하나는 다음과 같습니다.
puts Foo # "uninitialized constant Foo (NameError)"
이 오류를 정신적으로 "상수를 찾을 수 없음"으로 번역하기를 바랍니다.
이 오류를 이해하기 위한 한 가지 중요한 점은 Ruby 클래스가 상수라는 것입니다.
예 :
Array String Hash
첫 글자가 대문자이기 때문에 상수입니다.
클래스를 정의할 때 실제로 하는 일은 Class
를 생성하는 것입니다. 상수에 할당된 개체입니다.
상수는 클래스 이름이 됩니다.
이것이 왜 중요한가요?
"초기화되지 않은 상수" 오류가 표시되는 가장 큰 이유는 require
상수를 정의하는 파일 또는 gem.
아니면 상수 이름의 철자를 잘못 입력했을 수도 있습니다.
그러니 계속 주시하십시오.
상수는 변경될 수 있음
소개에서 언급했듯이 Ruby 상수는 변경될 수 있습니다.
예 :
ABC = 1 ABC = 2
하지만 다음과 같은 경고 메시지가 표시됩니다.
2: warning: already initialized constant ABC
프로그램은 여전히 잘 작동하지만 이것을 피하고 싶을 것입니다.
Ruby의 변수는 컨테이너가 아니라 단순히 객체에 대한 포인터이기 때문에 상수가 변경되는 것을 막을 방법이 없습니다.
또는 원하는 경우 레이블.
당신이 할 수 있는 최선은 변경할 수 없는 개체를 사용하는 것입니다.
예 :
AUTHOR = "Jesus Castello".freeze AUTHOR << "o" # RuntimeError: can't modify frozen String<블록 인용>
관련 기사 :루비의 가변성과 동결 방법.
이 예에서 AUTHOR
상수가 가리키는 유일한 것은 freeze
입니다. 개체 자체를 변경하지 못하도록 보호합니다.
상수 메소드
상수 작업 전용 방법이 몇 가지 있습니다.
메서드 | 설명 |
---|---|
상수 | 클래스에 정의된 상수를 나타내는 기호 배열을 반환합니다. |
const_get | 상수 값을 반환합니다. 기호 또는 문자열을 매개변수로 사용 |
const_set | 상수 값을 설정합니다. 두 개의 매개변수를 사용합니다. 상수 이름을 기호로 사용하고 상수 값 |
const_missing | method_missing 과 동일 하지만 상수 |
const_defined? | 주어진 상수(기호로)가 정의된 경우 true를 반환합니다. |
remove_const | 상수 제거 |
private_constant | Class::ABC 를 사용하여 클래스 외부에서 액세스할 수 없도록 상수를 비공개로 만듭니다. 구문 |
이러한 방법을 사용하여 수행할 수 있는 몇 가지 메타프로그래밍 트릭이 있습니다.
예 :
module Food class Bacon; end class Chocolate; end end puts "Classes defined inside #{Food}:" puts Food.constants
또한 "Array"와 같은 문자열을 사용하고 실제 클래스를 얻을 수 있습니다.
array_class = Object.const_get("Array")
그러나 문자열이 params
에서 오는 경우 사용자가 코드를 삽입할 수 있으므로 주의하십시오. 또는 다른 형태의 사용자 입력.
Rails에는 기본적으로 const_get
을 수행하는 상수화 메소드가 있습니다. 하지만 보안 검사는 하지 않는다는 점에 유의하세요.
치트시트
루비 상수 범위
클래스 외부에서 상수를 생성하면 코드의 최상위 수준에서 해당 상수를 어디에서나 사용할 수 있습니다.
상수는 자식 클래스에서도 사용할 수 있습니다.
class A FOO = 1 end class B < A def foo puts FOO end end B.constants # [:FOO]를 넣습니다.
중첩된 모듈 또는 클래스 외부에 정의된 상수는 중첩된 클래스 내부에서도 사용할 수 있습니다.
module Food STORE_ADDRESS = "The moon" class Bacon def foo; puts STORE_ADDRESS; end end end fb = Food::Bacon.new fb.foo # "The moon"
모듈 믹싱
혼합 모듈의 상수도 사용할 수 있습니다.
module Mixin A = 123 end class Product include Mixin puts A end # 123
이것은 모듈을 포함할 때 작동하지만 확장하는 경우 작동하지 않습니다.
예 :
class Product extend Mixin puts A end # uninitialized constant Product::A
또한 :
모듈에서 포함된 메소드를 사용할 때 Ruby는 해당 메소드가 정의된 위치에서 시작하여 상수를 찾습니다.
예 :
module Parent def print_value VALUE end end class Child include Parent VALUE = 1 end # Works p Child::VALUE # uninitialized constant Parent::VALUE p Child.new.print_value
명심해야 할 사항!
모듈 중첩
중첩된 클래스가 있는 예를 하나 더 보여 드리고자 합니다(모듈도 동일).
class A FOO = 1 end class A::B class C puts FOO end end
A::B
바로 가기로 사용하려고 시도한 표기법입니다. 하지만 문제는 C
클래스가 FOO
에 액세스할 수 없습니다. 직접.
이러한 이유로 다음과 같은 중첩 방식을 고수하고 싶습니다.
class A FOO = 1 end class A class B class C puts FOO end end end
첫 번째 예에서는 여전히 ::A::FOO
를 수행할 수 있습니다. 상수에 액세스하지만 클래스 이름이 변경되면 오류가 발생합니다.
이 ::A::FOO
구문이 작동하는 이유는 Ruby에게 Array
와 같은 상수가 있는 최상위 범위를 보도록 지시하기 때문입니다. &String
정의됩니다.
동영상
요약
몇 가지 흥미로운 동작을 하는 변수 유형인 Ruby 상수에 대해 배웠습니다. 상수 값을 변경할 수 있지만 경고가 출력됩니다.
또한 클래스 이름이 상수이고 const_get
을 피해야 한다는 것도 배웠습니다. 사용자 입력으로.
이 게시물이 마음에 드셨다면 공유하는 것을 잊지 마세요 더 많은 사람들이 상수의 작동 방식을 이해할 수 있도록 합니다.