Ruby 2.4

BasicObject

class BasicObject

父:

BasicObject是Ruby中所有类的父类。这是一个明确的空白类。

BasicObject可用于创建独立于Ruby对象层次结构的对象层次结构,Delegator类之类的代理对象或其他必须避免来自Ruby方法和类的命名空间污染的用途。

为避免污染其他用户的BasicObject,应该创建一个BasicObject的适当命名的子类,而不是直接修改BasicObject:

class MyObjectSystem < BasicObject end

BasicObject不包括内核(对于类似的方法puts),而BasicObject不在标准库的名称空间中,因此不使用完整的类路径就可以找到常见的类。

可以使用各种策略将标准库的有用部分提供给BasicObject的子类。子类include Kernel可以获得putsexit等等。可以创建和包含定制的内核模块,或者可以通过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

从Ruby标准库访问类和模块可以在BasicObject子类中通过引用根::File或类似的所需常量来获得::Enumerator。像method_missing一样,可以使用const_missing将常量查找委托给Object

class MyObjectSystem < BasicObject def self.const_missing(name) ::Object.const_get(name) end end

公共类方法

new() 显示源文件

没有记录

static VALUE rb_obj_dummy(void) { return Qnil; }

公共实例方法

!obj →true或false显示来源

布尔否定。

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

obj != other →true或false显示源

如果两个对象不相等则返回true,否则返回false。

VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2) { VALUE result = rb_funcall(obj1, id_eq, 1, obj2 return RTEST(result) ? Qfalse : Qtrue; }

obj == other→true或false显示来源

平等-在Object水平,==返回true只有当objother是同一对象。通常,这个方法在后代类中被覆盖以提供类特定的含义。

与此不同==,该equal?方法不应被子类覆盖,因为它用于确定对象标识(即,a.equal?(b)当且仅当a与对象相同时b):

obj = "a" other = obj.dup obj == other #=> true obj.equal? other #=> false obj.equal? obj #=> true

eql?方法返回trueif objother引用相同的散列键。Hash使用它来测试成员是否相等。对于课堂上的对象而言Object,它eql?是同义词==。子类通常通过别名eql?重写==方法来延续这一传统,但也有例外。Numeric类型,例如,执行类型转换==,但不跨越eql?,因此:

1 == 1.0 #=> true 1.eql? 1.0 #=> false

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

__id__→整数显示源文件

object_id→整数

返回一个整数标识符obj

object_id对于给定对象的所有调用都会返回相同的数字,并且没有两个活动对象将共享一个ID。

注意:内建类的一些对象被重新用于优化。立即值和冻结字符串文字就是这种情况。

立即值不按引用传递,而是由值传递:niltruefalse,Fixnums,符号,还有一些浮标。

Object.new.object_id == Object.new.object_id # => false (21 * 2).object_id == (21 * 2).object_id # => true "hello".object_id == "hello".object_id # => false "hi".freeze.object_id == "hi".freeze.object_id # => true

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 (STATIC_SYM_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...) →obj显示源

__send__(symbol , args...) → obj

send(string , args...) → obj

__send__(string , args...) → obj

调用由符号标识的方法,向其传递任何指定的参数。__send__如果名称sendobj中的现有方法冲突,则可以使用。当方法由字符串标识时,字符串将转换为符号

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

VALUE rb_f_send(int argc, VALUE *argv, VALUE recv) { return send_internal(argc, argv, recv, CALL_FCALL }

equal?(other) → true 或 false 显示资源

平等-在Object水平,==返回true只有当objother是同一对象。通常,这个方法在后代类中被覆盖以提供类特定的含义。

与此不同==,该equal?方法不应被子类覆盖,因为它用于确定对象标识(即,a.equal?(b)当且仅当a与对象相同时b):

obj = "a" other = obj.dup obj == other #=> true obj.equal? other #=> false obj.equal? obj #=> true

如果 objother引用相同的散列键,该eql?方法返回true。Hash使用它来测试成员是否相等。对于课堂上的对象而言Object,它eql?是同义词==。子类通常通过别名eql?重写==方法来延续这一传统,但也有例外。Numeric类型,例如,执行类型转换==,但不跨越eql?,因此:

1 == 1.0 #=> true 1.eql? 1.0 #=> false

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

instance_eval(string [, filename , lineno] ) →obj显示源文件

instance_eval {|obj| block } → obj

在接收器(obj)的上下文中评估包含Ruby源代码或给定块的字符串。为了设置上下文,在代码执行时变量self设置为obj,从而使代码可以访问obj的实例变量和私有方法。

instance_eval给定一个块时,obj也作为块的唯一参数传入。

instance_eval给定一个String时,可选的第二个和第三个参数提供报告编译错误时使用的文件名和起始行号。

class KlassWithSecret def initialize @secret = 99 end private def the_secret "Ssssh! The secret is #{@secret}." end end k = KlassWithSecret.new k.instance_eval { @secret } #=> 99 k.instance_eval { the_secret } #=> "Ssssh! The secret is 99." k.instance_eval {|obj| obj == self } #=> true

VALUE rb_obj_instance_eval(int argc, const VALUE *argv, VALUE self) { VALUE klass = singleton_class_for_eval(self return specific_eval(argc, argv, klass, self }

instance_exec(arg...) {|var...| block } → obj Show source

在接收器(obj)的上下文中执行给定的块。为了设置上下文,在代码执行时将该变量self设置为obj,从而使代码可以访问obj的实例变量。参数作为块参数传递。

class KlassWithSecret def initialize @secret = 99 end end k = KlassWithSecret.new k.instance_exec(5) {|x| @secret+x } #=> 104

VALUE rb_obj_instance_exec(int argc, const VALUE *argv, VALUE self) { VALUE klass = singleton_class_for_eval(self return yield_under(klass, self, argc, argv }

私有实例方法

method_missing(symbol , *args ) → result显示源文件

obj发送消息时,由Ruby调用它无法处理。符号是调用方法的符号args是传递给它的任何参数。默认情况下,解释器在调用此方法时引发错误。但是,可以重写该方法以提供更多动态行为。如果决定不应该处理某种特定方法,那么应该调用超级方法,以便祖先能够找到缺失的方法。下面的例子创建一个类Roman,它响应名称由罗马数字组成的方法,返回相应的整数值。

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

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

singleton_method_added(符号)显示源代码

无论何时将单例方法添加到接收方,都会调用回调函数。

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

生产:

Adding singleton_method_added Adding one Adding three

static VALUE rb_obj_dummy(void) { return Qnil; }

singleton_method_removed(符号)显示源

每当从接收器中删除一个单例方法时调用回调函数。

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

生产:

Removing three Removing one

static VALUE rb_obj_dummy(void) { return Qnil; }

singleton_method_undefined(符号)显示源代码

当接收器中的单例方法未定义时,作为回调调用。

module Chatty def Chatty.singleton_method_undefined(id) puts "Undefining #{id.id2name}" end def Chatty.one() end class << self undef_method(:one) end end

生产:

Undefining one

static VALUE rb_obj_dummy(void) { return Qnil; }