Programing

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

lottogame 2020. 2. 21. 22:00
반응형

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
puts Foo::MR_COUNT  # this is the local "Foo" constant

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가 아마도 당신이 찾고있는 것일 것입니다.


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

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

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

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


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

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

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


정의가 프로젝트에 연결된 다른 코드와 충돌하는 것을 방지하는 것입니다. 그것은 당신이 물건을 분리하여 유지할 수 있음을 의미합니다.

예를 들어 코드에 "run"이라는 하나의 메소드가있을 수 있으며 링크 된 다른 라이브러리에 정의 된 "run"메소드가 아닌 메소드를 계속 호출 할 수 있습니다.


Ruby on rails는 네임 스페이스 확인에 ::를 사용합니다.

class User < ActiveRecord::Base

  VIDES_COUNT = 10
  Languages = { "English" => "en", "Spanish" => "es", "Mandarin Chinese" => "cn"}

end

그것을 사용하려면 :

User::VIDEOS_COUNT
User::Languages
User::Languages.values_at("Spanish") => "en"

또한 다른 사용법은 중첩 경로를 사용할 때입니다.

OmniauthCallbacksController 사용자 아래에 정의되어 있습니다.

경로는 다음과 같습니다.

devise_for :users, controllers: {omniauth_callbacks: "users/omniauth_callbacks"}


class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

end

놀랍게도, 여기에있는 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

module Amimal
      module Herbivorous
            EATER="plants" 
      end
end

Amimal::Herbivorous::EATER => "plants"

:: 범위를 만드는 데 사용됩니다. 2 개의 모듈에서 Constant EATER에 액세스하려면 상수에 도달하도록 모듈의 범위를 지정해야합니다.

참고 URL : https://stackoverflow.com/questions/3009477/what-is-rubys-double-colon



반응형