[解決済み] eigenclassはself.classと同じように見えるのに、なぜ違うのですか?
疑問点
どこかでメモを取り損ねたので、説明してほしいのですが。
なぜオブジェクトの固有クラスは
self.class
?
class Foo
def initialize(symbol)
eigenclass = class << self
self
end
eigenclass.class_eval do
attr_accessor symbol
end
end
end
私の論理では、固有クラスと
class.self
を同一視する私の論理は、むしろ単純なものです。
class << self
は、インスタンスメソッドではなく、クラスメソッドを宣言する方法です。これは
def Foo.bar
.
というわけで、クラスオブジェクトへの参照内で
self
と同じになるはずです。
self.class
. これは
class << self
は
self
を
Foo.class
に変更し、クラスメソッド/属性の定義に使用します。
私が混乱しているだけなのでしょうか?それとも、これはRubyのメタプログラミングの巧妙なトリックなのでしょうか?
どのように解決するのですか?
class << self
は、単にクラスメソッドを宣言する方法以上のものです(そのように使うこともできますが)。 おそらく、次のような使い方を見たことがあるのではないでしょうか。
class Foo
class << self
def a
print "I could also have been defined as def Foo.a."
end
end
end
これは、次のように動作します。
def Foo.a
と同じですが、その動作は少し微妙です。 その秘密は
self
は、この文脈では、オブジェクト
Foo
の一意の匿名サブクラスであるオブジェクトを指します。
Class
. このサブクラスは
Foo
's
固有クラス
. そこで
def a
という新しいメソッドを作成します。
a
で
Foo
の固有クラスで、通常のメソッド呼び出し構文でアクセスできます。
Foo.a
.
では、別の例を見てみましょう。
str = "abc"
other_str = "def"
class << str
def frob
return self + "d"
end
end
print str.frob # => "abcd"
print other_str.frob # => raises an exception, 'frob' is not defined on other_str
この例は、最初はわかりにくいかもしれませんが、前回と同じです。
frob
が定義されていますが、その上ではなく
String
の固有値で定義されます。
str
の一意の匿名サブクラスである
String
. ですから
str
には
frob
メソッドがありますが、インスタンス
String
のインスタンスは一般にそうではありません。 また、Stringのメソッドをオーバーライドすることもできます (特定のトリッキーなテストシナリオで非常に便利です)。
これで、元の例を理解することができるようになりました。 内部
Foo
の initialize メソッドの中です。
self
はクラスではなく
Foo
というクラスではなく、ある特定の
インスタンス
の
Foo
. その固有クラスは
Foo
のサブクラスですが、それは
Foo
でなければ、2番目の例で見たようなトリックが働くはずがありません。 そうでなければ、2番目の例で見たトリックはうまくいきません。
f1 = Foo.new(:weasels)
f2 = Foo.new(:monkeys)
f1.weasels = 4 # Fine
f2.monkeys = 5 # Also ok
print(f1.monkeys) # Doesn't work, f1 doesn't have a 'monkeys' method.
これが役立つといいのですが。
関連
-
[解決済み] インスタンスメソッドをモンキーパッチする場合、新しい実装からオーバーライドされたメソッドを呼び出すことは可能ですか?
-
[解決済み] Rubyの文字列の中から"˶‾‾‾˵"を削除するにはどうしたらいいですか?
-
[解決済み] Rubyオプションのパラメータ
-
[解決済み] Ruby: HTTP でファイルを multipart/form-data で投稿するには?
-
[解決済み] Rubyのsend()は何をするのですか?
-
[解決済み] 最大値のハッシュのキーはどのように見つけるのですか?
-
[解決済み] Ruby: 文字列の最初の文字を取得する方法
-
[解決済み] Herokuの基本的なアプリのロードに2秒かかるのはなぜですか?
-
[解決済み] raise "foo"`と`raise Exception.new("foo")` の違いは何ですか?
-
[解決済み] バージョン要件におけるティルデグレータン(~>)の意味?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] なぜsumはinject(:+)よりもずっと速いのですか?
-
[解決済み] Gemfileでrubygemを指定するときの~>と>=の違いは何ですか?
-
[解決済み] 2つのハッシュを比較するにはどうすればよいですか?
-
[解決済み] インストールされているすべてのGemsを削除して最初からやり直す
-
[解決済み] ruby システムコマンドの終了コードチェック
-
[解決済み] RubyでDateTimeの時間部分を設定する
-
[解決済み] Ruby の文字列から最後の n 文字を抽出する。
-
[解決済み] RubyでCtrl-cをキャプチャする
-
[解決済み] Rubyで文字列中のある文字の出現回数を検索する
-
[解決済み] Rubyのモジュール/ミキシンからクラスメソッドを継承する