Skip to content

Instantly share code, notes, and snippets.

@hanachin
Last active April 12, 2018 19:16
Show Gist options
  • Save hanachin/d957cb6af37d6509a35393191ca87038 to your computer and use it in GitHub Desktop.
Save hanachin/d957cb6af37d6509a35393191ca87038 to your computer and use it in GitHub Desktop.
2018/4/11 Okinawa.rbでアナグラさんに聞かれたはなし

あるクラスまたはモジュールで定義された定数を外部から参照する ためには::'演算子を用います。またObjectクラスで 定義されている定数(トップレベルの定数と言う)を確実に参照する ためには左辺無しの::'演算子が使えます。 例:

module M
  I = 35
  class C
  end
end
p M::I   #=> 35
p M::C   #=> M::C
p ::M    #=> M

M::NewConst = 777   # => 777

https://docs.ruby-lang.org/ja/2.5.0/doc/spec=2fvariables.html

If a constant is defined at the top-level you may preceded it with :: to reference it: Z = 0

module A Z = 1

module B p ::Z #=> 0 end end https://docs.ruby-lang.org/en/2.5.0/syntax/modules_and_classes_rdoc.html#label-Constants

parse.y的にはここの文法 https://github.com/ruby/ruby/blob/v2_5_1/parse.y#L2751-L2759

NEW_COLON3はここで https://github.com/ruby/ruby/blob/v2_5_1/node.h#L447

このタイプのNODEできて https://github.com/ruby/ruby/blob/v2_5_1/node.h#L189-L190

ここでコンパイルされる https://github.com/ruby/ruby/blob/v2_5_1/compile.c#L4023-L4028

RubyのInstructionSequenceでObjectをputobjectでおいたあとgetconstantでObjectの定数を参照している感じ

トップレベルから::で参照するように書くと何が便利なんだろ?

  • トップレベルで定義されてるクラスと同名のクラスを宣言しているときトップレベルのクラスを参照できる
  • どのクラスを見るのかトップレベルかた辿ることで一意になるので、トップレベルで定義されているクラスと同名のクラスがあるソースの中にコピペしても動く
  • どんな環境で評価されるかわからないときトップレベルから参照しておくと期待していない定数を参照する可能性がなくなる

とかかな

FOO = :top_level
# top levelで定義するとObjectクラスの定数として定義される
p Object.constants.include?(:FOO) # => true
# Objectクラスの定数なのでObjectの後ろに::をつけて参照できる
p Object::FOO # => :top_level
module M
FOO = :M
# 名前がかぶっているときtop levelが参照できない
p FOO # => :M
# ::を使うと参照できる
p ::FOO # => :top_level
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment