Co to jest dwukropek Ruby `::`?

Co to jest dwukropek ::? Np. Foo::Bar.

Znalazłem definicję :

:: jest operatorem jednoargumentowym, który umożliwia dostęp do: stałych, metod instancji i metod klas zdefiniowanych w klasie lub module z dowolnego miejsca poza klasą lub modułem.

Po co jest scope (prywatny, chroniony), jeśli możesz użyć :: do ujawnienia czegokolwiek?

Author: sawa, 2010-06-09

10 answers

:: jest w zasadzie operatorem rozdzielczości przestrzeni nazw. Umożliwia dostęp do elementów w modułach lub elementów na poziomie klasy w klasach. Na przykład, powiedzmy, że masz taką konfigurację:

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

Możesz uzyskać dostęp CONSTANT spoza modułu jako SomeModule::InnerModule::MyClass::CONSTANT.

Nie ma to wpływu na metody instancji zdefiniowane w klasie, ponieważ uzyskujesz dostęp do tych z inną składnią(kropka .).

Odpowiednia uwaga: jeśli chcesz wrócić do przestrzeni nazw najwyższego poziomu, zrób to::: SomeModule - Benjamin Oakes

 389
Author: mipadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-09 18:30:07

Ilustruje to prosty przykład:

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

Wzięte z http://www.tutorialspoint.com/ruby/ruby_operators.htm

 118
Author: Nader,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-01 19:17:11

:: umożliwia dostęp do stałej, modułu lub klasy zdefiniowanej wewnątrz innej klasy lub modułu. Jest on używany do dostarczania przestrzeni nazw, aby nazwy metod i klas nie były sprzeczne z innymi klasami przez różnych autorów.

Kiedy widzisz ActiveRecord::Base w Rails oznacza to, że Rails ma coś w rodzaju

module ActiveRecord
  class Base
  end
end

Tzn. Klasa o nazwie Base wewnątrz modułu ActiveRecord, do którego odnosi się ActiveRecord::Base (można ją znaleźć w źródle Rails w ActiveRecord-N. N. N/lib/active_record/base. rb)

A często używa się:: is, aby uzyskać dostęp do stałych zdefiniowanych w modułach, np.

module Math
  PI = 3.141 # ...
end

puts Math::PI

Operator :: nie pozwala ominąć widoczności metod oznaczonych jako prywatne lub chronione.

 77
Author: mikej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-09 20:22:01

Jaki jest pożytek z scope (private, protected), jeśli możesz po prostu użyć::, aby cokolwiek ujawnić?

W Ruby, wszystko jest eksponowane i wszystko może być modyfikowane z dowolnego miejsca.

Jeśli martwisz się o to, że klasy mogą być zmieniane spoza "definicji klasy", to Ruby prawdopodobnie nie jest dla Ciebie.

Z drugiej strony, jeśli jesteś sfrustrowany zablokowaniem klas Javy, to Ruby jest prawdopodobnie tym, czego szukasz.

 29
Author: yfeldblum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-09 20:17:23

Dodawanie do poprzednich odpowiedzi jest poprawne, aby Ruby używał :: do uzyskiwania dostępu do metod instancji. Wszystkie poniższe są ważne:

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

zgodnie z najlepszymi praktykami uważam, że zaleca się tylko ostatnią.

 13
Author: Yuri Ghensev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-09 03:46:47

O dziwo, wszystkie 10 odpowiedzi mówi to samo. '::' Jest operatorem rozdzielczości przestrzeni nazw i tak, to prawda. Ale jest jedna sprawa, którą trzeba sobie uświadomić o operatorze rozdzielczości przestrzeni nazw, jeśli chodzi o algorytm constant lookup . Jak opisuje Matz w swojej książce "język programowania Ruby", constant lookup ma wiele kroków. Po pierwsze, przeszukuje stałą w zakres leksykalny gdzie stała jest odwołana. Jeśli nie znajdzie stała w zakresie leksykalnym, następnie przeszukuje hierarchię dziedziczenia . Ze względu na ten stały algorytm wyszukiwania, poniżej otrzymujemy oczekiwane wyniki:

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

Podczas gdy F dziedziczy od E, moduł B mieści się w zakresie leksykalnym F. W związku z tym instancje F będą odnosiły się do stałej PI zdefiniowanej w module B. Teraz, jeśli moduł B nie zdefiniował PI, instancje F będą odnosiły się do stałej PI zdefiniowanej w klasie nadrzędnej E.

Ale co by było, gdybyśmy użyli ':: 'raczej niż moduły zagnieżdżania? Czy uzyskamy taki sam wynik? Nie!

Używając operatora rozdzielczości przestrzeni nazw podczas definiowania zagnieżdżonych modułów, zagnieżdżone moduły I klasy nie mieszczą się już w leksykalnym zakresie ich zewnętrznych modułów. Jak widać poniżej, PI zdefiniowane w A::B nie jest w leksykalnym zakresie A::B::C:: D i dlatego otrzymujemy niezainicjalizowaną stałą, gdy próbujemy odwołać się do PI w metodzie instancji get_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
 12
Author: Donato,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-06 16:08:27

Nie, nie jest to dostęp do każdej metody, jest to operator "rozdzielczości", czyli używasz go do rozwiązywania zakresu (lub lokalizacji, którą możesz powiedzieć) symbolu stałego/statycznego.

Na przykład w pierwszej linii, Rails używa jej, aby znaleźć klasę bazową wewnątrz ActiveRecord.Moduł, w drugim służy do zlokalizowania metody klasowej (statycznej)klasy tras, itd, itd.

Nie służy do eksponowania czegokolwiek, służy do "lokalizowania" rzeczy wokół twojego lunety.

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

 11
Author: Francisco Soto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-09 20:17:54

Chodzi o zapobieganie kolizji definicji z innymi kodami powiązanymi z Twoim projektem. To znaczy, że możesz trzymać rzeczy osobno.

Na przykład możesz mieć jedną metodę o nazwie " run "w kodzie i nadal będziesz mógł wywoływać swoją metodę, a nie metodę" run " zdefiniowaną w innej bibliotece, do której się połączyłeś.

 4
Author: Mongus Pong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-09 20:13:40
module Amimal
      module Herbivorous
            EATER="plants" 
      end
end

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

:: służy do tworzenia zakresu . Aby uzyskać dostęp do Constant EATER z 2 modułów musimy scope Moduły dotrzeć do stałej

 3
Author: Francesca Rodricks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-09 04:31:55

Ruby on rails używa :: do rozdzielczości przestrzeni nazw.

class User < ActiveRecord::Base

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

end

Aby go użyć:

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

Również inne użycie to: podczas korzystania z zagnieżdżonych tras

OmniauthCallbacksController jest zdefiniowana w sekcji Użytkownicy.

I oznaczony jako:

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


class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

end
 3
Author: Pankhuri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-17 17:07:32