Class: BasicObject

Inherits:
Qnil show all
Defined in:
object.c,
class.c,
object.c

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)
    DELEGATE.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

Object

Instance Method Summary collapse

Constructor Details

#initializeObject (private)

Not documented


907
908
909
910
911
# File 'object.c', line 907

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 (private)

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

625
626
627
628
629
630
631
# File 'vm_eval.c', line 625

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);
    UNREACHABLE;
}

Instance Method Details

#!Object

Boolean negate.


183
184
185
186
187
# File 'object.c', line 183

VALUE
rb_obj_not(VALUE obj)
{
    return RTEST(obj) ? Qfalse : Qtrue;
}

#!=Object

Returns true if two objects are not-equal, otherwise false.


196
197
198
199
200
201
# File 'object.c', line 196

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 as it is used to determine object identity (that is, a.equal?(b) if and only if a is the same object as b):

obj = "a"
other = obj.dup

obj == other      #=> true
obj.equal? other  #=> false
obj.equal? obj    #=> true

The eql? method returns true if obj and other refer to the same hash key. This is used by Hash to test members for equality. For objects of class Object, eql? is synonymous with ==. Subclasses normally continue this tradition by aliasing eql? to their overridden == method, 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

Overloads:

  • #==(other) ⇒ Boolean

    Returns:

    • (Boolean)
  • #equal?(other) ⇒ Boolean

    Returns:

    • (Boolean)
  • #eql?(other) ⇒ Boolean

    Returns:

    • (Boolean)

141
142
143
144
145
146
# File 'object.c', line 141

VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    if (obj1 == obj2) return Qtrue;
    return Qfalse;
}

#hashFixnum

Generates a Fixnum hash value for this object.

This function must have the property that a.eql?(b) implies a.hash == b.hash.

The hash value is used by Hash class.

Any hash value that exceeds the capacity of a Fixnum will be truncated before being used.

Returns:


2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
# File 'gc.c', line 2364

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;
    }
    else if (FLONUM_P(obj)) {
#if SIZEOF_LONG == SIZEOF_VOIDP
	return LONG2NUM((SIGNED_VALUE)obj);
#else
	return LL2NUM((SIGNED_VALUE)obj);
#endif
    }
    else if (SPECIAL_CONST_P(obj)) {
	return LONG2NUM((SIGNED_VALUE)obj);
    }
    return nonspecial_obj_id(obj);
}

#send(symbol[, args...]) ⇒ Object #__send__(symbol[, args...]) ⇒ Object #send(string[, args...]) ⇒ Object #__send__(string[, args...]) ⇒ Object

Invokes the method identified by symbol, passing it any

arguments specified. You can use <code>__send__</code> if the name
+send+ clashes with an existing method in _obj_.
When the method is identified by a string, the string is converted
to a symbol.

   class Klass
     def hello(*args)
       "Hello " + args.join(' ')
     end
   end
   k = Klass.new
   k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"

Overloads:


907
908
909
910
911
# File 'vm_eval.c', line 907

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 as it is used to determine object identity (that is, a.equal?(b) if and only if a is the same object as b):

obj = "a"
other = obj.dup

obj == other      #=> true
obj.equal? other  #=> false
obj.equal? obj    #=> true

The eql? method returns true if obj and other refer to the same hash key. This is used by Hash to test members for equality. For objects of class Object, eql? is synonymous with ==. Subclasses normally continue this tradition by aliasing eql? to their overridden == method, 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

Overloads:

  • #==(other) ⇒ Boolean

    Returns:

    • (Boolean)
  • #equal?(other) ⇒ Boolean

    Returns:

    • (Boolean)
  • #eql?(other) ⇒ Boolean

    Returns:

    • (Boolean)

Returns:

  • (Boolean)

141
142
143
144
145
146
# File 'object.c', line 141

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

Overloads:

  • #instance_eval(string[, filename [, lineno]]) ⇒ Object

    Returns:

  • #instance_eval {|| ... } ⇒ Object

    Yields:

    • ()

    Returns:


1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
# File 'vm_eval.c', line 1614

VALUE
rb_obj_instance_eval(int argc, VALUE *argv, VALUE self)
{
    VALUE klass;

    if (SPECIAL_CONST_P(self)) {
	klass = rb_special_singleton_class(self);
    }
    else {
	klass = rb_singleton_class(self);
    }
    return specific_eval(argc, argv, klass, self);
}

#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

Yields:

  • (var...)

Returns:


1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
# File 'vm_eval.c', line 1646

VALUE
rb_obj_instance_exec(int argc, VALUE *argv, VALUE self)
{
    VALUE klass;

    if (SPECIAL_CONST_P(self)) {
	klass = rb_special_singleton_class(self);
    }
    else {
	klass = rb_singleton_class(self);
    }
    return yield_under(klass, self, rb_ary_new4(argc, argv));
}

#singleton_method_addedObject (private)

Not documented


907
908
909
910
911
# File 'object.c', line 907

static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

#singleton_method_removedObject (private)

Not documented


907
908
909
910
911
# File 'object.c', line 907

static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

#singleton_method_undefinedObject (private)

Not documented


907
908
909
910
911
# File 'object.c', line 907

static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}