Ruby 2.3.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > BasicObjectクラス
クラスの継承リスト: BasicObject
特殊な用途のために意図的にほとんど何も定義されていないクラスです。 Objectクラスの親にあたります。Ruby 1.9 以降で導入されました。
BasicObject クラスは Object クラスからほとんどのメソッドを取り除いたクラスです。
Object クラスは様々な便利なメソッドや Kernel から受け継いだ関数的メソッド を多数有しています。 これに対して、 BasicObject クラスはオブジェクトの同一性を識別したりメソッドを呼んだりする 最低限の機能の他は一切の機能を持っていません。
基本的にはほぼすべてのクラスの親は Object と考えて差し支えありません。 しかし、ある種のクラスを定義する際には Object クラスは持っているメソッドが多すぎる 場合があります。
例えば、 BasicObject#method_missingを利用して Proxy パターンを実 装する場合にはObject クラスに定義済みのメソッドはプロクシできないという 問題が発生します。このような場合に Object ではなく BasicObject から派生 して問題を解決できます。
通常のクラスは Object またはその他の適切なクラスから派生すべきです。 真に必要な場合にだけ BasicObject から派生してください。
class Proxy < BasicObject def initialize(target) @target = target end def method_missing(message, *args) @target.__send__(message, *args) end end proxy = Proxy.new("1") proxy.to_i #=> 1
! self -> bool
[permalink][rdoc]オブジェクトを真偽値として評価し、その論理否定を返します。
このメソッドは self が nil または false であれば真を、さもなくば偽を返します。 主に論理式の評価に伴って副作用を引き起こすことを目的に 再定義するものと想定されています。
このメソッドを再定義しても Ruby の制御式において nil や false 以外が偽として 扱われることはありません。
例
class NegationRecorder < BasicObject def initialize @count = 0 end attr_reader :count def ! @count += 1 super end end recorder = NegationRecorder.new !recorder !!!!!!!recorder puts 'hoge' if !recorder puts recorder.count #=> 3
例
class AnotherFalse < BasicObject def ! true end end another_false = AnotherFalse.new # another_falseは*真* puts "another false is a truth" if another_false #=> "another false is a truth"
self != other -> bool
[permalink][rdoc]オブジェクトが other と等しくないことを判定します。
デフォルトでは self == other を評価した後に結果を論理否定して返します。 このため、サブクラスで BasicObject#== を再定義しても != とは自動的に整合性が とれるようになっています。
ただし、 BasicObject#!= 自身や BasicObject#! を再定義した際には、ユーザーの責任で 整合性を保たなくてはなりません。
このメソッドは主に論理式の評価に伴って副作用を引き起こすことを目的に 再定義するものと想定されています。
[SEE_ALSO] BasicObject#==, BasicObject#!
例
class NonequalityRecorder < BasicObject def initialize @count = 0 end attr_reader :count def !=(other) @count += 1 super end end recorder = NonequalityRecorder.new recorder != 1 puts 'hoge' if recorder != "str" p recorder.count #=> 2
self == other -> bool
[permalink][rdoc]オブジェクトが other と等しければ真を、さもなくば偽を返します。
このメソッドは各クラスの性質に合わせて、サブクラスで再定義するべきです。 多くの場合、オブジェクトの内容が等しければ真を返すように (同値性を判定するように) 再定義 することが期待されています。
デフォルトでは Object#equal? と同じオブジェクトの同一性になっています。
例:
class Person < BasicObject def initialize(name, age) @name = name @age = age end end tanaka1 = Person.new("tanaka", 24) tanaka2 = Person.new("tanaka", 24) tanaka1 == tanaka1 #=> true tanaka1 == tanaka2 #=> false
[SEE_ALSO] BasicObject#equal?, Object#==, Object#equal?, Object#eql?
__id__ -> Integer
[permalink][rdoc]各オブジェクトに対して一意な整数を返します。あるオブジェクトに対し てどのような整数が割り当てられるかは不定です。
Object#object_id と同じですが、#object_id は BasicObject に はない事に注意してください。
例:
# frozen_string_literal: false obj = Object.new obj.object_id == obj.__id__ # => true Object.new.__id__ == Object.new.__id__ # => false (21 * 2).__id__ == (21 * 2).__id__ # => true "hello".__id__ == "hello".__id__ # => false "hi".freeze.__id__ == "hi".freeze.__id__ # => true
[SEE_ALSO] Object#object_id, [ruby-dev:42840]
__send__(name, *args) -> object
[permalink][rdoc]__send__(name, *args) { .... } -> object
オブジェクトのメソッド name を args を引数にして呼び出し、メソッドの結果を返します。
ブロック付きで呼ばれたときはブロックもそのまま引き渡します。
例:
class Mail def delete(*args) "(Mail#delete) - delete " + args.join(',') end def send(name, *args) "(Mail#send) - #{name} #{args.join(',')}" end end mail = Mail.new mail.send :delete, "gentle", "readers" # => "(Mail#send) - delete gentle,readers" mail.__send__ :delete, "gentle", "readers" # => "(Mail#delete) - delete gentle,readers"
[SEE_ALSO] Object#__send__
equal?(other) -> bool
[permalink][rdoc]オブジェクトが other と同一であれば真を、さもなくば偽を返します。
このメソッドは2つのオブジェクトが同一のものであるかどうかを判定します。 一般にはこのメソッドを決して再定義すべきでありません。 ただし、 BasicObject の位置づけ上、どうしても再定義が必要な用途もあるでしょう。 再定義する際には自分が何をしているのかよく理解してから実行してください。
例:
original = "a" copied = original.dup substituted = original original == copied #=> true original == substituted #=> true original.equal? copied #=> false original.equal? substituted #=> true
[SEE_ALSO] Object#equal?, Object#==, Object#eql?
instance_eval(expr, filename = "(eval)", lineno = 1) -> object
[permalink][rdoc]instance_eval {|obj| ... } -> object
オブジェクトのコンテキストで文字列 expr またはオブジェクト自身をブロックパラメータとするブロックを 評価してその結果を返します。
オブジェクトのコンテキストで評価するとは評価中の self をそのオブジェクトにして実行するということです。 また、文字列 expr やブロック中でメソッドを定義すればそのオブジェクトの特異メソッドが定義されます。
ただし、ローカル変数だけは、文字列 expr の評価では instance_eval の外側のスコープと、ブロックの評価ではそのブロックの外側のスコープと、共有します。
メソッド定義の中で instance_eval でメソッドを定義した場合は、囲むメソッドが実行されたときに 初めて instance_eval 内のメソッドが定義されます。これはメソッド定義のネストと同じです。 クラス/メソッドの定義/メソッド定義のネスト を参照してください。
BasicObject を継承して作ったクラス内で instance_eval する場合はトップレベルの定数や Kernel モジュールに定義されているメソッドは見えません。 これは、トップレベルの定数が Object 以下に作成されるためです。
例:
class Foo def initialize data @key = data end private def do_fuga p 'secret' end end some = Foo.new 'XXX' some.instance_eval{p @key} #=> "XXX" some.instance_eval{do_fuga } #=> "secret" # private メソッドも呼び出せる some.instance_eval 'raise' # ..:10: (eval):1: (RuntimeError) messg = 'unknown' some.instance_eval 'raise messg','file.rb',999 # file.rb:999: unknown (RuntimeError)
例:
class Bar < BasicObject def call1 instance_eval("::ENV.class") end def call2 instance_eval("ENV.class") end end bar = Bar.new bar.call1 # => Object bar.call2 # raise NameError
[SEE_ALSO] Module#module_eval, Kernel.#eval
instance_exec(*args) {|*vars| ... } -> object
[permalink][rdoc]与えられたブロックをレシーバのコンテキストで実行します。
ブロック実行中は、 self がレシーバのコンテキストになるので レシーバの持つインスタンス変数にアクセスすることができます。
class KlassWithSecret def initialize @secret = 99 end end k = KlassWithSecret.new # 以下で x には 5 が渡される k.instance_exec(5) {|x| @secret + x } #=> 104
[SEE_ALSO] Module#class_exec, Module#module_exec, BasicObject#instance_eval
method_missing(name, *args) -> object
[permalink][rdoc]呼びだされたメソッドが定義されていなかった時、Rubyインタプリタがこのメソッド を呼び出します。
呼び出しに失敗したメソッドの名前 (Symbol) が name に その時の引数が第二引数以降に渡されます。
デフォルトではこのメソッドは例外 NoMethodError を発生させます。
class Foo def initialize(data) @data = data end def method_missing(name, lang) if name.to_s =~ /\Afind_(\d+)_in\z/ if @data[lang] p @data[lang][$1.to_i] else raise "#{lang} unknown" end else super end end end dic = Foo.new({:English => %w(zero one two), :Esperanto => %w(nulo unu du)}) dic.find_2_in :Esperanto #=> "du"
[注意] このメソッドを override する場合は対象のメソッド名に対して Object#respond_to? が真を返すようにしてください。 そのためには、Object#respond_to_missing? も同様に override する必 要があります。
[SEE_ALSO] Object#respond_to?, Object#respond_to_missing?
singleton_method_added(name) -> object
[permalink][rdoc]特異メソッドが追加された時にインタプリタから呼び出されます。
通常のメソッドの追加に対するフックには Module#method_addedを使います。
class Foo def singleton_method_added(name) puts "singleton method \"#{name}\" was added" end end obj = Foo.new def obj.foo end #=> singleton method "foo" was added
[SEE_ALSO] Module#method_added,BasicObject#singleton_method_removed,BasicObject#singleton_method_undefined
singleton_method_removed(name) -> object
[permalink][rdoc]特異メソッドが Module#remove_method に より削除された時にインタプリタから呼び出されます。
通常のメソッドの削除に対するフックには Module#method_removedを使います。
class Foo def singleton_method_removed(name) puts "singleton method \"#{name}\" was removed" end end obj = Foo.new def obj.foo end class << obj remove_method :foo end #=> singleton method "foo" was removed
[SEE_ALSO] Module#method_removed,BasicObject#singleton_method_added,BasicObject#singleton_method_undefined
singleton_method_undefined(name) -> object
[permalink][rdoc]特異メソッドが Module#undef_method または undef により未定義にされた時にインタプリタから呼び出されます。
通常のメソッドの未定義に対するフックには Module#method_undefined を使います。
class Foo def singleton_method_undefined(name) puts "singleton method \"#{name}\" was undefined" end end obj = Foo.new def obj.foo end def obj.bar end class << obj undef_method :foo end obj.instance_eval {undef bar} #=> singleton method "foo" was undefined # singleton method "bar" was undefined
[SEE_ALSO] Module#method_undefined,BasicObject#singleton_method_added,BasicObject#singleton_method_removed , クラス/メソッドの定義/undef