Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby 상수에 대해 알아야 할 모든 것

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을 수행하는 상수화 메소드가 있습니다. 하지만 보안 검사는 하지 않는다는 점에 유의하세요.

치트시트

Ruby 상수에 대해 알아야 할 모든 것

루비 상수 범위

클래스 외부에서 상수를 생성하면 코드의 최상위 수준에서 해당 상수를 어디에서나 사용할 수 있습니다.

상수는 자식 클래스에서도 사용할 수 있습니다.

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을 피해야 한다는 것도 배웠습니다. 사용자 입력으로.

이 게시물이 마음에 드셨다면 공유하는 것을 잊지 마세요 더 많은 사람들이 상수의 작동 방식을 이해할 수 있도록 합니다.