[ruby] Ruby의 이중 콜론`::`은 무엇입니까?

이 이중 콜론은 무엇입니까 ::? 예 Foo::Bar.

정의를 찾았습니다 .

::허용 단항 연산자 : 클래스 또는 모듈 내에 정의 된 상수, 인스턴스 메소드와 클래스 메소드는 클래스 또는 모듈의 외부를 통해 액세스된다.

무엇 ::이든 노출 하기 위해 사용할 수 있다면 스코프 (개인, 보호) 는 무엇입니까?



답변

::기본적으로 네임 스페이스 확인 연산자입니다. 모듈의 항목 또는 클래스의 클래스 레벨 항목에 액세스 할 수 있습니다. 예를 들어, 다음과 같이 설정했다고 가정하십시오.

module SomeModule
    module InnerModule
        class MyClass
            CONSTANT = 4
        end
    end
end

CONSTANT모듈 외부에서로 액세스 할 수 있습니다 SomeModule::InnerModule::MyClass::CONSTANT.

다른 구문 (dot .)으로 액세스하기 때문에 클래스에 정의 된 인스턴스 메소드에는 영향을 미치지 않습니다 .

관련 참고 사항 : 최상위 네임 스페이스로 돌아가려면 다음과 같이하십시오. :: SomeModule – Benjamin Oakes


답변

이 간단한 예는 다음을 보여줍니다.

MR_COUNT = 0        # constant defined on main Object class
module Foo
  MR_COUNT = 0
  ::MR_COUNT = 1    # set global count to 1
  MR_COUNT = 2      # set local count to 2
end

puts MR_COUNT       # this is the global constant: 1
puts Foo::MR_COUNT  # this is the local constant: 2

http://www.tutorialspoint.com/ruby/ruby_operators.htm 에서 가져옴


답변

::다른 클래스 또는 모듈 내에 정의 된 상수, 모듈 또는 클래스에 액세스 할 수 있습니다. 메소드와 클래스 이름이 다른 작성자의 다른 클래스와 충돌하지 않도록 네임 스페이스를 제공하는 데 사용됩니다.

ActiveRecord::BaseRails에서 볼 때 Rails는

module ActiveRecord
  class Base
  end
end

즉, Base모듈 내부에서 호출 된 클래스 ActiveRecord는 다음과 같이 참조됩니다 ActiveRecord::Base(activerecord-nnn / lib / active_record / base.rb의 Rails 소스에서 찾을 수 있습니다)

::의 일반적인 용도는 모듈에 정의 된 상수에 액세스하는 것입니다.

module Math
  PI = 3.141 # ...
end

puts Math::PI

::방법의 바이 패스 가시성을 허용하지 않습니다 운영자는 개인 또는 보호 표시했다.


답변

::를 사용하여 아무것도 노출시킬 수 있다면 스코프 (개인, 보호)는 무엇입니까?

루비에서는 모든 것이 노출되고 다른 곳에서 모든 것을 수정할 수 있습니다.

클래스가 “클래스 정의”외부에서 변경 될 수 있다는 사실이 걱정된다면 Ruby가 적합하지 않을 것입니다.

반면에, Java의 클래스가 잠겨있어 좌절한다면 Ruby가 아마도 당신이 찾고있는 것일 것입니다.


답변

이전 답변에 추가하여 ::인스턴스 메소드에 액세스 하는 데 유효한 Ruby 입니다. 다음은 모두 유효합니다.

MyClass::new::instance_method
MyClass::new.instance_method
MyClass.new::instance_method
MyClass.new.instance_method

모범 사례에 따라 마지막 것만 권장한다고 생각합니다.


답변

아니요, 모든 방법에 액세스하는 것이 아니라 “해상도”연산자입니다. 즉, 상수 / 정적 기호의 범위 (또는 말할 수있는 위치)를 해결하는 데 사용합니다.

예를 들어 첫 번째 줄에서 Rails는 ActiveRecord.Module 내에서 Base 클래스를 찾는 데 사용하고 두 번째 줄에서는 Routes 클래스 등의 클래스 메서드 (정적)를 찾는 데 사용됩니다.

그것은 당신의 스코프 주위에 물건을 위치시키는 데 사용되는 것을 드러내는 데 사용되지 않습니다.

http://en.wikipedia.org/wiki/Scope_resolution_operator


답변

놀랍게도, 여기에있는 10 개의 답변은 모두 같은 것을 말합니다. ‘::’는 네임 스페이스 확인 연산자이며, 그렇습니다. 그러나 상수 조회 알고리즘과 관련 하여 네임 스페이스 확인 연산자에 대해 알아야 할 사항이 하나 있습니다 . Matz가 그의 책 ‘The Ruby Programming Language’에서 묘사 한 것처럼, 지속적인 검색은 여러 단계를 거칩니다. 먼저, 상수가 참조되는 어휘 범위 에서 상수를 검색합니다 . 어휘 범위 내에서 상수를 찾지 못하면 상속 계층 구조 를 검색합니다 . 이 상수 조회 알고리즘으로 인해 아래 예상 결과를 얻습니다.

module A
  module B
      PI = 3.14
      module C
        class E
          PI = 3.15
        end
        class F < E
          def get_pi
            puts PI
          end
        end
      end
  end
end
f = A::B::C::F.new
f.get_pi
> 3.14

F가 E에서 상속되는 동안 B 모듈은 F의 어휘 범위 내에 있습니다. 따라서 F 인스턴스는 모듈 B에 정의 된 상수 PI를 참조합니다. 이제 모듈 B가 PI를 정의하지 않은 경우 F 인스턴스는 PI를 참조합니다. 수퍼 클래스 E에 정의 된 상수

그러나 중첩 모듈 대신 ‘::’을 사용한다면 어떨까요? 같은 결과를 얻을 수 있을까요? 아니!

중첩 모듈을 정의 할 때 네임 스페이스 확인 연산자를 사용하면 중첩 모듈과 클래스가 더 이상 외부 모듈의 어휘 범위 내에 있지 않습니다. 아래에서 볼 수 있듯이 A :: B에 정의 된 PI는 A :: B :: C :: D의 어휘 범위에 있지 않으므로 get_pi 인스턴스 메소드에서 PI를 참조하려고 할 때 초기화되지 않은 상수를 얻습니다.

module A
end

module A::B
  PI = 3.14
end

module A::B::C
  class D
    def get_pi
      puts PI
    end
  end
end
d = A::B::C::D.new
d.get_pi
NameError: uninitialized constant A::B::C::D::PI
Did you mean?  A::B::PI