概要
Rubyのクラス宣言について混乱することがあったため、具体例を交えて自分の理解をまとめました。
これらが正しいのかどうか分かりかねているので、参考資料や誤りのご指摘をいただきたいです。
環境情報
$ uname -a Linux centos7 3.10.0-514.el7.x86_64 #1 SMP Tue Nov 22 16:42:41 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux $ ruby -v ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]
ディレクトリ構成
以下のディレクトリ構成でPattern AとPattern Bにおいてruby mail.rb
を実行する
. ├── hoge │ └── foo.rb ├── hoge.rb └── main.rb
Pattern A
hoge.rb
class Hoge < Array; end
hoge/foo.rb
class Hoge class Foo; end end
main.rb
エラーにならない
require './hoge' require './hoge/foo'
エラーになる
require './hoge/foo' require './hoge'
エラー内容
/home/user/tmp/hoge.rb:1:in `<top (required)>': superclass mismatch for class Hoge (TypeError) from /home/user/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' from /home/user/.rbenv/versions/2.3.1/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require' from main.rb:7:in `<main>'
Pattern B
hoge.rb
class Hoge < Array; end
hoge/foo.rb
class Hoge < Array class Foo; end end
main.rb
Pattern Bでは以下両方の例でエラーにならない。
require './hoge' require './hoge/foo'
require './hoge/foo' require './hoge'
Rubyのクラス宣言に関する私の理解
- Rubyのクラス定義(
class XXX
またはClass.new('XXX')
)はObject
定数(クラス)へXXXという名前の定数を定義することである
$ irb irb(main):001:0> class Hoge; end => nil irb(main):002:0> ::Object::Hoge => Hoge
- Rubyでは同名のクラス定義は複数回行える
irb(main):007:0> class Foo; end => nil irb(main):008:0> class Foo; end => nil irb(main):009:0> class Foo; end => nil irb(main):010:0* class Foo; end => nil
- クラス定義は複数回行えるが、元のクラスと異なるスーパークラスを指定すると TypeError が発生する
- 複数回クラス宣言を行う場合、2回目以降は継承関係の指定がなければ既に宣言された継承関係であると暗黙に見なす(Stringとの継承関係が消えることはない)
class Hoge < Array; end class Hoge class Foo; end end Hoge.new.is_a?(Array) # true

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/05/14 16:06