BasicObject
class BasicObject
父:
BasicObject是Ruby中所有类的父类。这是一个明确的空白类。
BasicObject可用于创建独立于Ruby对象层次结构的对象层次结构,Delegator类之类的代理对象或其他必须避免来自Ruby方法和类的命名空间污染的用途。
为避免污染其他用户的BasicObject,应该创建一个BasicObject的适当命名的子类,而不是直接修改BasicObject:
class MyObjectSystem < BasicObject
end
BasicObject不包括内核(对于类似的方法puts
),而BasicObject不在标准库的名称空间中,因此不使用完整的类路径就可以找到常见的类。
可以使用各种策略将标准库的有用部分提供给BasicObject的子类。子类include Kernel
可以获得puts
,exit
等等。可以创建和包含定制的内核模块,或者可以通过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
只有当obj
和other
是同一对象。通常,这个方法在后代类中被覆盖以提供类特定的含义。
与此不同==
,该equal?
方法不应被子类覆盖,因为它用于确定对象标识(即,a.equal?(b)
当且仅当a
与对象相同时b
):
obj = "a"
other = obj.dup
obj == other #=> true
obj.equal? other #=> false
obj.equal? obj #=> true
该eql?
方法返回true
if obj
和other
引用相同的散列键。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。
注意:内建类的一些对象被重新用于优化。立即值和冻结字符串文字就是这种情况。
立即值不按引用传递,而是由值传递:nil
,true
,false
,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__
如果名称send
与obj中
的现有方法冲突,则可以使用。当方法由字符串标识时,字符串将转换为符号
。
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
只有当obj
和other
是同一对象。通常,这个方法在后代类中被覆盖以提供类特定的含义。
与此不同==
,该equal?
方法不应被子类覆盖,因为它用于确定对象标识(即,a.equal?(b)
当且仅当a
与对象相同时b
):
obj = "a"
other = obj.dup
obj == other #=> true
obj.equal? other #=> false
obj.equal? obj #=> true
如果 obj
和other
引用相同的散列键,该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;
}