Class: BasicObject
Overview
BasicObject is the parent class of all classes in Ruby. It's an explicit blank class.
BasicObject can be used for creating object hierarchies independent of Ruby's object hierarchy, proxy objects like the Delegator class, or other uses where namespace pollution from Ruby's methods and classes must be avoided.
To avoid polluting BasicObject for other users an appropriately named subclass of BasicObject should be created instead of directly modifying BasicObject:
class MyObjectSystem < BasicObject
end
BasicObject does not include Kernel (for methods like puts
) and BasicObject is outside of the namespace of the standard library so common classes will not be found without a using a full class path.
A variety of strategies can be used to provide useful portions of the standard library to subclasses of BasicObject. A subclass could include Kernel
to obtain puts
, exit
, etc. A custom Kernel-like module could be created and included or delegation can be used via #method_missing:
class MyObjectSystem < BasicObject
DELEGATE = [:puts, :p]
def method_missing(name, *args, &block)
super unless DELEGATE.include? name
::Kernel.send(name, *args, &block)
end
def respond_to_missing?(name, include_private = false)
DELGATE.include?(name) or super
end
end
Access to classes and modules from the Ruby standard library can be obtained in a BasicObject subclass by referencing the desired constant from the root like ::File
or ::Enumerator
. Like #method_missing, #const_missing can be used to delegate constant lookup to Object
:
class MyObjectSystem < BasicObject
def self.const_missing(name)
::Object.const_get(name)
end
end
Direct Known Subclasses
Instance Method Summary collapse
-
#! ⇒ Object
Boolean negate.
-
#!= ⇒ Object
Returns true if two objects are not-equal, otherwise false.
-
#== ⇒ Object
Equality---At the
Object
level,==
returnstrue
only if obj and other are the same object. -
#__id__ ⇒ Object
call-seq: obj.__id__ -> fixnum obj.object_id -> fixnum.
-
#__send__ ⇒ Object
Invokes the method identified by symbol, passing it any arguments specified.
-
#equal? ⇒ Object
Equality---At the
Object
level,==
returnstrue
only if obj and other are the same object. -
#new ⇒ Object
constructor
Returns a new BasicObject.
-
#instance_eval ⇒ Object
Evaluates a string containing Ruby source code, or the given block, within the context of the receiver (obj).
-
#instance_exec(arg...) {|var...| ... } ⇒ Object
Executes the given block within the context of the receiver (obj).
-
#method_missing(symbol[, *args]) ⇒ Object
Invoked by Ruby when obj is sent a message it cannot handle.
-
#singleton_method_added(symbol) ⇒ Object
Invoked as a callback whenever a singleton method is added to the receiver.
-
#singleton_method_removed(symbol) ⇒ Object
Invoked as a callback whenever a singleton method is removed from the receiver.
-
#singleton_method_undefined(symbol) ⇒ Object
Invoked as a callback whenever a singleton method is undefined in the receiver.
Constructor Details
#new ⇒ Object
Returns a new BasicObject.
|
# File 'object.c'
/*
* Not documented
*/
static VALUE
rb_obj_dummy(void)
{
return Qnil;
}
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(symbol[, *args]) ⇒ Object
Invoked by Ruby when obj is sent a message it cannot handle. symbol is the symbol for the method called, and args are any arguments that were passed to it. By default, the interpreter raises an error when this method is called. However, it is possible to override the method to provide more dynamic behavior. If it is decided that a particular method should not be handled, then super should be called, so that ancestors can pick up the missing method. The example below creates a class Roman
, which responds to methods with names consisting of roman numerals, returning the corresponding integer values.
class Roman
def roman_to_int(str)
# ...
end
def method_missing(methId)
str = methId.id2name
roman_to_int(str)
end
end
r = Roman.new
r.iv #=> 4
r.xxiii #=> 23
r.mm #=> 2000
|
# File 'vm_eval.c'
static VALUE
rb_method_missing(int argc, const VALUE *argv, VALUE obj)
{
rb_thread_t *th = GET_THREAD();
raise_method_missing(th, argc, argv, obj, th->method_missing_reason);
return Qnil; /* not reached */
}
|
Instance Method Details
#! ⇒ Object
Boolean negate.
|
# File 'object.c'
VALUE
rb_obj_not(VALUE obj)
{
return RTEST(obj) ? Qfalse : Qtrue;
}
|
#!= ⇒ Object
Returns true if two objects are not-equal, otherwise false.
|
# File 'object.c'
VALUE
rb_obj_not_equal(VALUE obj1, VALUE obj2)
{
VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
return RTEST(result) ? Qfalse : Qtrue;
}
|
#==(other) ⇒ Boolean #equal?(other) ⇒ Boolean #eql?(other) ⇒ Boolean
Equality---At the Object
level, ==
returns true
only if obj and other are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.
Unlike ==
, the equal?
method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b)
iff a
is the same object as b
).
The eql?
method returns true
if obj and anObject have the same value. Used by Hash
to test members for equality. For objects of class Object
, eql?
is synonymous with ==
. Subclasses normally continue this tradition, but there are exceptions. Numeric
types, for example, perform type conversion across ==
, but not across eql?
, so:
1 == 1.0 #=> true
1.eql? 1.0 #=> false
|
# File 'object.c'
VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
if (obj1 == obj2) return Qtrue;
return Qfalse;
}
|
#__id__ ⇒ Object
call-seq:
obj.__id__ -> fixnum
obj.object_id -> fixnum
Returns an integer identifier for obj. The same number will be returned on all calls to id
for a given object, and no two active objects will share an id. Object#object_id
is a different concept from the :name
notation, which returns the symbol id of name
. Replaces the deprecated Object#id
.
|
# File 'gc.c'
/*
* call-seq:
* obj.hash -> fixnum
*
* Generates a <code>Fixnum</code> hash value for this object. This
* function must have the property that <code>a.eql?(b)</code> implies
* <code>a.hash == b.hash</code>. The hash value is used by class
* <code>Hash</code>. Any hash value that exceeds the capacity of a
* <code>Fixnum</code> will be truncated before being used.
*/
VALUE
rb_obj_id(VALUE obj)
{
/*
* 32-bit VALUE space
* MSB ------------------------ LSB
* false 00000000000000000000000000000000
* true 00000000000000000000000000000010
* nil 00000000000000000000000000000100
* undef 00000000000000000000000000000110
* symbol ssssssssssssssssssssssss00001110
* object oooooooooooooooooooooooooooooo00 = 0 (mod sizeof(RVALUE))
* fixnum fffffffffffffffffffffffffffffff1
*
* object_id space
* LSB
* false 00000000000000000000000000000000
* true 00000000000000000000000000000010
* nil 00000000000000000000000000000100
* undef 00000000000000000000000000000110
* symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
* object oooooooooooooooooooooooooooooo0 o...o % A = 0
* fixnum fffffffffffffffffffffffffffffff1 bignum if required
*
* where A = sizeof(RVALUE)/4
*
* sizeof(RVALUE) is
* 20 if 32-bit, double is 4-byte aligned
* 24 if 32-bit, double is 8-byte aligned
* 40 if 64-bit
*/
if (SYMBOL_P(obj)) {
return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
}
|
#send(symbol[, args...]) ⇒ Object #__send__(symbol[, args...]) ⇒ Object
Invokes the method identified by symbol, passing it any arguments specified. You can use __send__
if the name send
clashes with an existing method in obj.
class Klass
def hello(*args)
"Hello " + args.join(' ')
end
end
k = Klass.new
k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
|
# File 'vm_eval.c'
VALUE
rb_f_send(int argc, VALUE *argv, VALUE recv)
{
return send_internal(argc, argv, recv, CALL_FCALL);
}
|
#==(other) ⇒ Boolean #equal?(other) ⇒ Boolean #eql?(other) ⇒ Boolean
Equality---At the Object
level, ==
returns true
only if obj and other are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.
Unlike ==
, the equal?
method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b)
iff a
is the same object as b
).
The eql?
method returns true
if obj and anObject have the same value. Used by Hash
to test members for equality. For objects of class Object
, eql?
is synonymous with ==
. Subclasses normally continue this tradition, but there are exceptions. Numeric
types, for example, perform type conversion across ==
, but not across eql?
, so:
1 == 1.0 #=> true
1.eql? 1.0 #=> false
|
# File 'object.c'
VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
if (obj1 == obj2) return Qtrue;
return Qfalse;
}
|
#instance_eval(string[, filename [, lineno]]) ⇒ Object #instance_eval {|| ... } ⇒ Object
Evaluates a string containing Ruby source code, or the given block, within the context of the receiver (obj). In order to set the context, the variable self
is set to obj while the code is executing, giving the code access to obj's instance variables. In the version of instance_eval
that takes a String
, the optional second and third parameters supply a filename and starting line number that are used when reporting compilation errors.
class KlassWithSecret
def initialize
@secret = 99
end
end
k = KlassWithSecret.new
k.instance_eval { @secret } #=> 99
|
# File 'vm_eval.c'
VALUE
rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
{
VALUE klass;
if (SPECIAL_CONST_P(self)) {
klass = Qnil;
}
|
#instance_exec(arg...) {|var...| ... } ⇒ Object
Executes the given block within the context of the receiver (obj). In order to set the context, the variable self
is set to obj while the code is executing, giving the code access to obj's instance variables. Arguments are passed as block parameters.
class KlassWithSecret
def initialize
@secret = 99
end
end
k = KlassWithSecret.new
k.instance_exec(5) {|x| @secret+x } #=> 104
|
# File 'vm_eval.c'
VALUE
rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
{
VALUE klass;
if (SPECIAL_CONST_P(self)) {
klass = Qnil;
}
|
#singleton_method_added(symbol) ⇒ Object
Invoked as a callback whenever a singleton method is added to the receiver.
module Chatty
def Chatty.singleton_method_added(id)
puts "Adding #{id.id2name}"
end
def self.one() end
def two() end
def Chatty.three() end
end
produces:
Adding singleton_method_added
Adding one
Adding three
|
# File 'object.c'
/*
* Not documented
*/
static VALUE
rb_obj_dummy(void)
{
return Qnil;
}
|
#singleton_method_removed(symbol) ⇒ Object
Invoked as a callback whenever a singleton method is removed from the receiver.
module Chatty
def Chatty.singleton_method_removed(id)
puts "Removing #{id.id2name}"
end
def self.one() end
def two() end
def Chatty.three() end
class << self
remove_method :three
remove_method :one
end
end
produces:
Removing three
Removing one
|
# File 'object.c'
/*
* Not documented
*/
static VALUE
rb_obj_dummy(void)
{
return Qnil;
}
|
#singleton_method_undefined(symbol) ⇒ Object
Invoked as a callback whenever a singleton method is undefined in the receiver.
module Chatty
def Chatty.singleton_method_undefined(id)
puts "Undefining #{id.id2name}"
end
def Chatty.one() end
class << self
undef_method(:one)
end
end
produces:
Undefining one
|
# File 'object.c'
/*
* Not documented
*/
static VALUE
rb_obj_dummy(void)
{
return Qnil;
}
|