SlideShare a Scribd company logo
1 of 17
Download to read offline
Module での名前解決について
2017/12/7
@cuzic
表参道.rb #29 発表資料 「Module での名前解決について」
1自己紹介
Tomoya Kawanishi a.k.a cuzic
エネチェンジ株式会社 チーフエンジニア
エンジニア、積極採用してます!
Ruby関西の中の人
みなさん、登壇お願いします!
Otemachi.rb 主催
11月28日(火) Otemachi.rb #1 を開催しました。
表参道.rb #29 発表資料 「Module での名前解決について」
モジュールでの名前解決
クラスの継承関係などを通じて、どのように名前解決さ
れるかをします
定数、インスタンス変数、クラス変数、メソッドなど
クイズ形式で進行しますので、お楽しみください
2
表参道.rb #29 発表資料 「Module での名前解決について」
定数の名前解決
親クラスの定数は子クラスからも参照できる
外側のモジュールの定数は内側からも参照できる
3
class Base
A = 1
end
class Sub<Base
def self.a
A
end
end
puts Sub.a #=> 1
module Outer
B = 10
class Sub<Base
def self.b
B
end
end
end
puts Outer::Sub.b #=> 10
表参道.rb #29 発表資料 「Module での名前解決について」
Q: 定数の名前解決
継承関係とモジュールのネスト、
名前が衝突した場合、どちらが優先されるか?
4
class Base
A = 1
def self.a
A
end
end
module Outer
A = 2
class Sub<Base
def self.a2
A
end
end
end
puts Base.a #=> 1
puts Outer::Sub.a #=> ?
puts Outer::Sub.a2 #=> ?
表参道.rb #29 発表資料 「Module での名前解決について」
A: 定数の名前解決
両方が見える場所では継承関係よりもネストの外側にあ
る方が優先されます。
5
module Outer
A = 2
class Sub<Base
def self.a2
A
end
end
end
puts Base.a #=> 1
puts Outer::Sub.a #=> 1
puts Outer::Sub.a2 #=> 2
class Base
A = 1
def self.a
A
end
end
表参道.rb #29 発表資料 「Module での名前解決について」
定数の名前解決(こぼれ話)
ネストしていない場合、外側の定数は参照できません
6
class Base
A = 1
end
module Outer
A = 2
class Sub<Base
end
end
class Outer::Sub
def a3
A
end
end
puts Outer::Sub.a3 #=> 1
表参道.rb #29 発表資料 「Module での名前解決について」
Q: クラス変数
クラス変数は、継承関係をまたいでアクセスできる
子クラスで、値を更新したとき、
親クラスに影響するか?
7
class Base
@@a = 1
def self.a
@@a
end
end
class Sub<Base
def self.set_a
@@a = 2
end
end
puts Base.a #=> 1
puts Sub.a #=> 1
Sub.set_a
puts Base.a #=> ?
puts Sub.a #=> 2
表参道.rb #29 発表資料 「Module での名前解決について」
A: クラス変数
クラス変数は名前空間がクラスの継承関係で、スコープ
が区切られたグローバル変数と思うと理解しやすい
子クラスでの更新は
親クラスにも影響する
8
class Base
@@a = 1
def self.a
@@a
end
end
class Sub<Base
def self.set_a
@@a = 2
end
end
puts Base.a #=> 1
puts Sub.a #=> 1
Sub.set_a
puts Base.a #=> 2
puts Sub.a #=> 2
表参道.rb #29 発表資料 「Module での名前解決について」
補足:クラス変数
Ruby on Rails ではクラス変数の利用を避け、
class_attribute を使うことが推奨される
class_attribute では、
子クラスで更新しても
親クラスには影響しない
9
require 'active_support' +
'/core_ext/class/attribute'
class Base
class_attribute :a
self.a = 1
end
class Sub<Base
def self.set_a
self.a = 2
end
end
puts Base.a #=> 1
puts Sub.a #=> 1
Sub.set_a #=> 2
puts Base.a #=> 1
puts Sub.a #=> 2
表参道.rb #29 発表資料 「Module での名前解決について」
Q: クラスインスタンス変数
Ruby はすべてがオブジェクト。クラスもオブジェクト
クラスのインスタンス変数がクラスインスタンス変数
子クラスから親クラスのクラスインスタンス変数にアク
セスできるか?
10
class Base
@a = 1
def self.a1
@a
end
end
class Sub<Base
def self.a2
@a
end
end
p Base.a1 #=> 1
p Sub.a1 #=> ?
p Sub.a2 #=> ?
表参道.rb #29 発表資料 「Module での名前解決について」
A: クラスインスタンス変数
子クラスからは親クラスのクラスインスタンス変数には
アクセスできない
クラスインスタンス変数はより狭いスコープとなる
そのクラスでしか使わないときは有用
クラス変数はスコープが広すぎるので、狭くしても問題ないとき
はクラスインスタンス変数を使うとベター。
11
class Base
@a = 1
def self.a1
@a
end
end
class Sub<Base
def self.a2
@a
end
end
p Base.a1 #=> 1
p Sub.a1 #=> nil
p Sub.a2 #=> nil
表参道.rb #29 発表資料 「Module での名前解決について」
Q: クラスコンテキストでのローカル変数
ローカル変数と同じ名前のメソッドがあったとき、
どちらが優先されるか?
クラスを再度開きなおしたとき、ローカル変数のスコー
プはどうなるか?
12
class Base
a = 1
def a
10
end
def a1
a
end
define_method :a2 do
a
end
end
class Base
define_method :a3 do
a
end
end
base = Base.new
puts base.a #=> 10
puts base.a1 #=> ?
puts base.a2 #=> ?
puts base.a3 #=> ?
表参道.rb #29 発表資料 「Module での名前解決について」
A: クラスコンテキストでのローカル変数
def は、新しいスコープを作り、その外側のローカル変
数は参照できない。
ブロックからは外側のローカル変数も参照できる
ローカル変数があれば、メソッド呼び出しより優先される
新たに開きなおすとスコープが区切られ、その中で定義
したローカル変数しか参照できない
13
class Base
a = 1
def a
10
end
def a1
a
end
define_method :a2 do
a
end
end
class Base
define_method :a3 do
a
end
end
base = Base.new
puts base.a #=> 10
puts base.a1 #=> 10
puts base.a2 #=> 1
puts base.a3 #=> 10
表参道.rb #29 発表資料 「Module での名前解決について」
(こぼれ話)class_eval と instance_eval
class_eval の中での def はインスタンスメソッドで、
instance_eval での def はクラスメソッドとなる
言葉と逆になるので、
ときおり混乱する
14
class Base
class_eval do
def a
"class_eval"
end
end
instance_eval do
def a
"instance_eval"
end
end
end
puts Base.a #=> instance_eval
puts Base.new.a #=> class_eval
表参道.rb #29 発表資料 「Module での名前解決について」
結びとして
Module、Class での名前解決についてクイズ形式で解説
しました
私自身とても勉強になりました
知らないと気づくまで非常に時間がかかる不具合になる
ような仕様もあります。
また、懇親会等で感想を聞かせてください。
15
16
ご清聴ありがとう
ございました

More Related Content

What's hot

[社内勉強会]ELBとALBと数万スパイク負荷テスト
[社内勉強会]ELBとALBと数万スパイク負荷テスト[社内勉強会]ELBとALBと数万スパイク負荷テスト
[社内勉強会]ELBとALBと数万スパイク負荷テストTakahiro Moteki
 
超実践 Cloud Spanner 設計講座
超実践 Cloud Spanner 設計講座超実践 Cloud Spanner 設計講座
超実践 Cloud Spanner 設計講座Samir Hammoudi
 
freee API の歩みと今後のロードマップ
freee API の歩みと今後のロードマップfreee API の歩みと今後のロードマップ
freee API の歩みと今後のロードマップfreee株式会社
 
EmbulkとDigdagとデータ分析基盤と
EmbulkとDigdagとデータ分析基盤とEmbulkとDigdagとデータ分析基盤と
EmbulkとDigdagとデータ分析基盤とToru Takahashi
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ SEGADevTech
 
SolrとElasticsearchを比べてみよう
SolrとElasticsearchを比べてみようSolrとElasticsearchを比べてみよう
SolrとElasticsearchを比べてみようShinsuke Sugaya
 
AWS Blackbelt 2015シリーズ Amazon EC2 Container Service (Amazon ECS)
AWS Blackbelt 2015シリーズ Amazon EC2 Container Service (Amazon ECS)AWS Blackbelt 2015シリーズ Amazon EC2 Container Service (Amazon ECS)
AWS Blackbelt 2015シリーズ Amazon EC2 Container Service (Amazon ECS)Amazon Web Services Japan
 
Spring Boot ユーザの方のための Quarkus 入門
Spring Boot ユーザの方のための Quarkus 入門Spring Boot ユーザの方のための Quarkus 入門
Spring Boot ユーザの方のための Quarkus 入門tsukasamannen
 
正しいものを正しく作る塾-設計コース
正しいものを正しく作る塾-設計コース正しいものを正しく作る塾-設計コース
正しいものを正しく作る塾-設計コース増田 亨
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門泰 増田
 
20220409 AWS BLEA 開発にあたって検討したこと
20220409 AWS BLEA 開発にあたって検討したこと20220409 AWS BLEA 開発にあたって検討したこと
20220409 AWS BLEA 開発にあたって検討したことAmazon Web Services Japan
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ増田 亨
 
世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計増田 亨
 
3週連続DDDその1 ドメイン駆動設計の基本を理解する
3週連続DDDその1  ドメイン駆動設計の基本を理解する3週連続DDDその1  ドメイン駆動設計の基本を理解する
3週連続DDDその1 ドメイン駆動設計の基本を理解する増田 亨
 
こわくない Git
こわくない Gitこわくない Git
こわくない GitKota Saito
 
DevOpsに求められる様々な技術とその連携の学習方法
DevOpsに求められる様々な技術とその連携の学習方法DevOpsに求められる様々な技術とその連携の学習方法
DevOpsに求められる様々な技術とその連携の学習方法CASAREAL, Inc.
 
AWS Lambdaのテストで役立つ各種ツール
AWS Lambdaのテストで役立つ各種ツールAWS Lambdaのテストで役立つ各種ツール
AWS Lambdaのテストで役立つ各種ツールMasaki Suzuki
 
C# における Redis 徹底活用
C# における Redis 徹底活用C# における Redis 徹底活用
C# における Redis 徹底活用Takaaki Suzuki
 

What's hot (20)

[社内勉強会]ELBとALBと数万スパイク負荷テスト
[社内勉強会]ELBとALBと数万スパイク負荷テスト[社内勉強会]ELBとALBと数万スパイク負荷テスト
[社内勉強会]ELBとALBと数万スパイク負荷テスト
 
超実践 Cloud Spanner 設計講座
超実践 Cloud Spanner 設計講座超実践 Cloud Spanner 設計講座
超実践 Cloud Spanner 設計講座
 
freee API の歩みと今後のロードマップ
freee API の歩みと今後のロードマップfreee API の歩みと今後のロードマップ
freee API の歩みと今後のロードマップ
 
EmbulkとDigdagとデータ分析基盤と
EmbulkとDigdagとデータ分析基盤とEmbulkとDigdagとデータ分析基盤と
EmbulkとDigdagとデータ分析基盤と
 
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~ CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
 
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_cccSpring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
Spring Boot on Kubernetes : Yahoo!ズバトク事例 #jjug_ccc
 
SolrとElasticsearchを比べてみよう
SolrとElasticsearchを比べてみようSolrとElasticsearchを比べてみよう
SolrとElasticsearchを比べてみよう
 
AWS Blackbelt 2015シリーズ Amazon EC2 Container Service (Amazon ECS)
AWS Blackbelt 2015シリーズ Amazon EC2 Container Service (Amazon ECS)AWS Blackbelt 2015シリーズ Amazon EC2 Container Service (Amazon ECS)
AWS Blackbelt 2015シリーズ Amazon EC2 Container Service (Amazon ECS)
 
Spring Boot ユーザの方のための Quarkus 入門
Spring Boot ユーザの方のための Quarkus 入門Spring Boot ユーザの方のための Quarkus 入門
Spring Boot ユーザの方のための Quarkus 入門
 
正しいものを正しく作る塾-設計コース
正しいものを正しく作る塾-設計コース正しいものを正しく作る塾-設計コース
正しいものを正しく作る塾-設計コース
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門PlaySQLAlchemy: SQLAlchemy入門
PlaySQLAlchemy: SQLAlchemy入門
 
20220409 AWS BLEA 開発にあたって検討したこと
20220409 AWS BLEA 開発にあたって検討したこと20220409 AWS BLEA 開発にあたって検討したこと
20220409 AWS BLEA 開発にあたって検討したこと
 
マイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチマイクロサービス 4つの分割アプローチ
マイクロサービス 4つの分割アプローチ
 
世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計
 
3週連続DDDその1 ドメイン駆動設計の基本を理解する
3週連続DDDその1  ドメイン駆動設計の基本を理解する3週連続DDDその1  ドメイン駆動設計の基本を理解する
3週連続DDDその1 ドメイン駆動設計の基本を理解する
 
こわくない Git
こわくない Gitこわくない Git
こわくない Git
 
DevOpsに求められる様々な技術とその連携の学習方法
DevOpsに求められる様々な技術とその連携の学習方法DevOpsに求められる様々な技術とその連携の学習方法
DevOpsに求められる様々な技術とその連携の学習方法
 
AWS Lambdaのテストで役立つ各種ツール
AWS Lambdaのテストで役立つ各種ツールAWS Lambdaのテストで役立つ各種ツール
AWS Lambdaのテストで役立つ各種ツール
 
C# における Redis 徹底活用
C# における Redis 徹底活用C# における Redis 徹底活用
C# における Redis 徹底活用
 

Similar to Module での名前解決について

クラスのインスタンス変数について
クラスのインスタンス変数についてクラスのインスタンス変数について
クラスのインスタンス変数についてTomoya Kawanishi
 
名古屋Ruby会議02 LT:Ruby中級への道
名古屋Ruby会議02 LT:Ruby中級への道名古屋Ruby会議02 LT:Ruby中級への道
名古屋Ruby会議02 LT:Ruby中級への道Shigeru UCHIYAMA
 
Ruby2.0 - refinements - 鳥取Ruby会 第11回
Ruby2.0 - refinements - 鳥取Ruby会 第11回Ruby2.0 - refinements - 鳥取Ruby会 第11回
Ruby2.0 - refinements - 鳥取Ruby会 第11回Rie HIRONO
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogrammingMasanori Kado
 
Ruby and ActiveSupport for expart
Ruby and ActiveSupport for expartRuby and ActiveSupport for expart
Ruby and ActiveSupport for expartxibbar
 
Perlでちょいモテデザインパターン
PerlでちょいモテデザインパターンPerlでちょいモテデザインパターン
PerlでちょいモテデザインパターンYuki Manno
 
Ruby on Rails 入門
Ruby on Rails 入門Ruby on Rails 入門
Ruby on Rails 入門Yasuko Ohba
 

Similar to Module での名前解決について (7)

クラスのインスタンス変数について
クラスのインスタンス変数についてクラスのインスタンス変数について
クラスのインスタンス変数について
 
名古屋Ruby会議02 LT:Ruby中級への道
名古屋Ruby会議02 LT:Ruby中級への道名古屋Ruby会議02 LT:Ruby中級への道
名古屋Ruby会議02 LT:Ruby中級への道
 
Ruby2.0 - refinements - 鳥取Ruby会 第11回
Ruby2.0 - refinements - 鳥取Ruby会 第11回Ruby2.0 - refinements - 鳥取Ruby会 第11回
Ruby2.0 - refinements - 鳥取Ruby会 第11回
 
20110820 metaprogramming
20110820 metaprogramming20110820 metaprogramming
20110820 metaprogramming
 
Ruby and ActiveSupport for expart
Ruby and ActiveSupport for expartRuby and ActiveSupport for expart
Ruby and ActiveSupport for expart
 
Perlでちょいモテデザインパターン
PerlでちょいモテデザインパターンPerlでちょいモテデザインパターン
Perlでちょいモテデザインパターン
 
Ruby on Rails 入門
Ruby on Rails 入門Ruby on Rails 入門
Ruby on Rails 入門
 

More from Tomoya Kawanishi

ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例Tomoya Kawanishi
 
エンジニア転職のノウハウ
エンジニア転職のノウハウエンジニア転職のノウハウ
エンジニア転職のノウハウTomoya Kawanishi
 
Ruby の文字列について
Ruby の文字列についてRuby の文字列について
Ruby の文字列についてTomoya Kawanishi
 
Ruby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてRuby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてTomoya Kawanishi
 
Ruby初心者からよく質問されること
Ruby初心者からよく質問されることRuby初心者からよく質問されること
Ruby初心者からよく質問されることTomoya Kawanishi
 
RubyGems と Bundler について
RubyGems と Bundler についてRubyGems と Bundler について
RubyGems と Bundler についてTomoya Kawanishi
 
Ruby の正規表現について
Ruby の正規表現についてRuby の正規表現について
Ruby の正規表現についてTomoya Kawanishi
 
Ruby での外部コマンドの実行について
Ruby での外部コマンドの実行についてRuby での外部コマンドの実行について
Ruby での外部コマンドの実行についてTomoya Kawanishi
 
Ruby のワンライナーについて
Ruby のワンライナーについてRuby のワンライナーについて
Ruby のワンライナーについてTomoya Kawanishi
 
AWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことAWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことTomoya Kawanishi
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選Tomoya Kawanishi
 
HTTPと Webクローリングについて
HTTPと WebクローリングについてHTTPと Webクローリングについて
HTTPと WebクローリングについてTomoya Kawanishi
 
Active record query interface
Active record query interfaceActive record query interface
Active record query interfaceTomoya Kawanishi
 
Active Support のコア拡張機能について
Active Support のコア拡張機能についてActive Support のコア拡張機能について
Active Support のコア拡張機能についてTomoya Kawanishi
 
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーRuby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーTomoya Kawanishi
 
RubyのDir、File、IO について
RubyのDir、File、IO についてRubyのDir、File、IO について
RubyのDir、File、IO についてTomoya Kawanishi
 
Thread の利用事例紹介
Thread の利用事例紹介Thread の利用事例紹介
Thread の利用事例紹介Tomoya Kawanishi
 
Ruby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてRuby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてTomoya Kawanishi
 

More from Tomoya Kawanishi (20)

英単語の覚え方
英単語の覚え方英単語の覚え方
英単語の覚え方
 
ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例ENECHANGE社での Scout APM 利用事例
ENECHANGE社での Scout APM 利用事例
 
エンジニア転職のノウハウ
エンジニア転職のノウハウエンジニア転職のノウハウ
エンジニア転職のノウハウ
 
Ruby の文字列について
Ruby の文字列についてRuby の文字列について
Ruby の文字列について
 
Ruby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構についてRuby on Rails のキャッシュ機構について
Ruby on Rails のキャッシュ機構について
 
Ruby初心者からよく質問されること
Ruby初心者からよく質問されることRuby初心者からよく質問されること
Ruby初心者からよく質問されること
 
RubyGems と Bundler について
RubyGems と Bundler についてRubyGems と Bundler について
RubyGems と Bundler について
 
Ruby の正規表現について
Ruby の正規表現についてRuby の正規表現について
Ruby の正規表現について
 
Ruby での外部コマンドの実行について
Ruby での外部コマンドの実行についてRuby での外部コマンドの実行について
Ruby での外部コマンドの実行について
 
Ruby のワンライナーについて
Ruby のワンライナーについてRuby のワンライナーについて
Ruby のワンライナーについて
 
AWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったことAWS のコスト管理をちゃんとしたくてやったこと
AWS のコスト管理をちゃんとしたくてやったこと
 
PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選PostgreSQL のイケてるテクニック7選
PostgreSQL のイケてるテクニック7選
 
HTTPと Webクローリングについて
HTTPと WebクローリングについてHTTPと Webクローリングについて
HTTPと Webクローリングについて
 
Rake
RakeRake
Rake
 
Active record query interface
Active record query interfaceActive record query interface
Active record query interface
 
Active Support のコア拡張機能について
Active Support のコア拡張機能についてActive Support のコア拡張機能について
Active Support のコア拡張機能について
 
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナーRuby ビジネス創出展 Ruby初心者向けプログラミングセミナー
Ruby ビジネス創出展 Ruby初心者向けプログラミングセミナー
 
RubyのDir、File、IO について
RubyのDir、File、IO についてRubyのDir、File、IO について
RubyのDir、File、IO について
 
Thread の利用事例紹介
Thread の利用事例紹介Thread の利用事例紹介
Thread の利用事例紹介
 
Ruby の制御構造とリテラルについて
Ruby の制御構造とリテラルについてRuby の制御構造とリテラルについて
Ruby の制御構造とリテラルについて
 

Module での名前解決について

  • 2. 表参道.rb #29 発表資料 「Module での名前解決について」 1自己紹介 Tomoya Kawanishi a.k.a cuzic エネチェンジ株式会社 チーフエンジニア エンジニア、積極採用してます! Ruby関西の中の人 みなさん、登壇お願いします! Otemachi.rb 主催 11月28日(火) Otemachi.rb #1 を開催しました。
  • 3. 表参道.rb #29 発表資料 「Module での名前解決について」 モジュールでの名前解決 クラスの継承関係などを通じて、どのように名前解決さ れるかをします 定数、インスタンス変数、クラス変数、メソッドなど クイズ形式で進行しますので、お楽しみください 2
  • 4. 表参道.rb #29 発表資料 「Module での名前解決について」 定数の名前解決 親クラスの定数は子クラスからも参照できる 外側のモジュールの定数は内側からも参照できる 3 class Base A = 1 end class Sub<Base def self.a A end end puts Sub.a #=> 1 module Outer B = 10 class Sub<Base def self.b B end end end puts Outer::Sub.b #=> 10
  • 5. 表参道.rb #29 発表資料 「Module での名前解決について」 Q: 定数の名前解決 継承関係とモジュールのネスト、 名前が衝突した場合、どちらが優先されるか? 4 class Base A = 1 def self.a A end end module Outer A = 2 class Sub<Base def self.a2 A end end end puts Base.a #=> 1 puts Outer::Sub.a #=> ? puts Outer::Sub.a2 #=> ?
  • 6. 表参道.rb #29 発表資料 「Module での名前解決について」 A: 定数の名前解決 両方が見える場所では継承関係よりもネストの外側にあ る方が優先されます。 5 module Outer A = 2 class Sub<Base def self.a2 A end end end puts Base.a #=> 1 puts Outer::Sub.a #=> 1 puts Outer::Sub.a2 #=> 2 class Base A = 1 def self.a A end end
  • 7. 表参道.rb #29 発表資料 「Module での名前解決について」 定数の名前解決(こぼれ話) ネストしていない場合、外側の定数は参照できません 6 class Base A = 1 end module Outer A = 2 class Sub<Base end end class Outer::Sub def a3 A end end puts Outer::Sub.a3 #=> 1
  • 8. 表参道.rb #29 発表資料 「Module での名前解決について」 Q: クラス変数 クラス変数は、継承関係をまたいでアクセスできる 子クラスで、値を更新したとき、 親クラスに影響するか? 7 class Base @@a = 1 def self.a @@a end end class Sub<Base def self.set_a @@a = 2 end end puts Base.a #=> 1 puts Sub.a #=> 1 Sub.set_a puts Base.a #=> ? puts Sub.a #=> 2
  • 9. 表参道.rb #29 発表資料 「Module での名前解決について」 A: クラス変数 クラス変数は名前空間がクラスの継承関係で、スコープ が区切られたグローバル変数と思うと理解しやすい 子クラスでの更新は 親クラスにも影響する 8 class Base @@a = 1 def self.a @@a end end class Sub<Base def self.set_a @@a = 2 end end puts Base.a #=> 1 puts Sub.a #=> 1 Sub.set_a puts Base.a #=> 2 puts Sub.a #=> 2
  • 10. 表参道.rb #29 発表資料 「Module での名前解決について」 補足:クラス変数 Ruby on Rails ではクラス変数の利用を避け、 class_attribute を使うことが推奨される class_attribute では、 子クラスで更新しても 親クラスには影響しない 9 require 'active_support' + '/core_ext/class/attribute' class Base class_attribute :a self.a = 1 end class Sub<Base def self.set_a self.a = 2 end end puts Base.a #=> 1 puts Sub.a #=> 1 Sub.set_a #=> 2 puts Base.a #=> 1 puts Sub.a #=> 2
  • 11. 表参道.rb #29 発表資料 「Module での名前解決について」 Q: クラスインスタンス変数 Ruby はすべてがオブジェクト。クラスもオブジェクト クラスのインスタンス変数がクラスインスタンス変数 子クラスから親クラスのクラスインスタンス変数にアク セスできるか? 10 class Base @a = 1 def self.a1 @a end end class Sub<Base def self.a2 @a end end p Base.a1 #=> 1 p Sub.a1 #=> ? p Sub.a2 #=> ?
  • 12. 表参道.rb #29 発表資料 「Module での名前解決について」 A: クラスインスタンス変数 子クラスからは親クラスのクラスインスタンス変数には アクセスできない クラスインスタンス変数はより狭いスコープとなる そのクラスでしか使わないときは有用 クラス変数はスコープが広すぎるので、狭くしても問題ないとき はクラスインスタンス変数を使うとベター。 11 class Base @a = 1 def self.a1 @a end end class Sub<Base def self.a2 @a end end p Base.a1 #=> 1 p Sub.a1 #=> nil p Sub.a2 #=> nil
  • 13. 表参道.rb #29 発表資料 「Module での名前解決について」 Q: クラスコンテキストでのローカル変数 ローカル変数と同じ名前のメソッドがあったとき、 どちらが優先されるか? クラスを再度開きなおしたとき、ローカル変数のスコー プはどうなるか? 12 class Base a = 1 def a 10 end def a1 a end define_method :a2 do a end end class Base define_method :a3 do a end end base = Base.new puts base.a #=> 10 puts base.a1 #=> ? puts base.a2 #=> ? puts base.a3 #=> ?
  • 14. 表参道.rb #29 発表資料 「Module での名前解決について」 A: クラスコンテキストでのローカル変数 def は、新しいスコープを作り、その外側のローカル変 数は参照できない。 ブロックからは外側のローカル変数も参照できる ローカル変数があれば、メソッド呼び出しより優先される 新たに開きなおすとスコープが区切られ、その中で定義 したローカル変数しか参照できない 13 class Base a = 1 def a 10 end def a1 a end define_method :a2 do a end end class Base define_method :a3 do a end end base = Base.new puts base.a #=> 10 puts base.a1 #=> 10 puts base.a2 #=> 1 puts base.a3 #=> 10
  • 15. 表参道.rb #29 発表資料 「Module での名前解決について」 (こぼれ話)class_eval と instance_eval class_eval の中での def はインスタンスメソッドで、 instance_eval での def はクラスメソッドとなる 言葉と逆になるので、 ときおり混乱する 14 class Base class_eval do def a "class_eval" end end instance_eval do def a "instance_eval" end end end puts Base.a #=> instance_eval puts Base.new.a #=> class_eval
  • 16. 表参道.rb #29 発表資料 「Module での名前解決について」 結びとして Module、Class での名前解決についてクイズ形式で解説 しました 私自身とても勉強になりました 知らないと気づくまで非常に時間がかかる不具合になる ような仕様もあります。 また、懇親会等で感想を聞かせてください。 15