来自Ruby世界似乎是这样说的,“Ruby内一切都是对象”。
有趣的一切都是对象,那么一切也就没有不再是对象了?
"面向对象的设计方法是在结构化编程对控制流程实现了结构化后,又加上了对数据的结构化。"——《松本行弘的程序世界》
这里引用自《Ruby Hacking Guide》的对象一章的说法,对象存在的必要条件
- 能够区分自身与其它(拥有标识)
- 能够响应请求(方法)
- 保持内部状态(实例变量)
Ruby 中的类层次结构
然后我们再看看一个有意思的结果:
irb(main):022:0> Object.class
=> Class
irb(main):023:0> Object.superclass
=> BasicObject
irb(main):024:0> BasicObject.superclass
=> nil
irb(main):025:0>
这里使用的是1.9.3版本的ruby,于是这是Ruby的类层次结构,至于为什么是这样的,不凡看看下面的这些代码。
void
Init_class_hierarchy(void)
{
rb_cBasicObject = boot_defclass("BasicObject", 0);
rb_cObject = boot_defclass("Object", rb_cBasicObject);
rb_cModule = boot_defclass("Module", rb_cObject);
rb_cClass = boot_defclass("Class", rb_cModule);
rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
RBASIC_SET_CLASS(rb_cClass, rb_cClass);
RBASIC_SET_CLASS(rb_cModule, rb_cClass);
RBASIC_SET_CLASS(rb_cObject, rb_cClass);
RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
}
这是用于初化化类层次的代码,也就是hierarchy的意思,层次,层次结构。
至于,boot_defclass那么就看看下面的
static VALUE
boot_defclass(const char *name, VALUE super)
{
VALUE obj = rb_class_boot(super);
ID id = rb_intern(name);
rb_name_class(obj, id);
rb_const_set((rb_cObject ? rb_cObject : obj), id, obj);
return obj;
}
如果这里还有什么令人不明白的地方,那么可能就是VALUE了。
原文是这么长:
#if defined HAVE_UINTPTR_T && 0
typedef uintptr_t VALUE;
typedef uintptr_t ID;
# define SIGNED_VALUE intptr_t
# define SIZEOF_VALUE SIZEOF_UINTPTR_T
# undef PRI_VALUE_PREFIX
#elif SIZEOF_LONG == SIZEOF_VOIDP
typedef unsigned long VALUE;
typedef unsigned long ID;
# define SIGNED_VALUE long
# define SIZEOF_VALUE SIZEOF_LONG
# define PRI_VALUE_PREFIX "l"
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
typedef unsigned LONG_LONG VALUE;
typedef unsigned LONG_LONG ID;
# define SIGNED_VALUE LONG_LONG
# define LONG_LONG_VALUE 1
# define SIZEOF_VALUE SIZEOF_LONG_LONG
# define PRI_VALUE_PREFIX PRI_LL_PREFIX
#else
# error ---->> ruby requires sizeof(void*) == sizeof(long) or sizeof(LONG_LONG) to be compiled. <<----
#endif
那么,简化一下为和前几个版本一致的,那么就是
typedef unsigned long VALUE;
原本的模型应该是这样的
Ruby的对象变的
让我们再简单看一看一个示例
irb(main):025:0> 1.class
=> Fixnum
irb(main):026:0> Fixnum.class
=> Class
irb(main):027:0> Fixnum.superclass
=> Integer
irb(main):028:0> Fixnum.superclass.superclass
=> Numeric
irb(main):029:0> Fixnum.superclass.superclass.superclass
=> Object
irb(main):030:0> Fixnum.superclass.superclass.superclass.superclass
=> BasicObject
irb(main):031:0>
好吧,我觉得引用RHG中的图来说明可能会更简单一点,只是这张图只能做一时只用
(转载保留Phodal's
BlogPhodal'szenthink)
因为这些都已经改变了
原先的对象只有这些
#define R_CAST(st) (struct st*)
#define RBASIC(obj) (R_CAST(RBasic)(obj))
#define ROBJECT(obj) (R_CAST(RObject)(obj))
#define RCLASS(obj) (R_CAST(RClass)(obj))
#define RMODULE(obj) RCLASS(obj)
#define RFLOAT(obj) (R_CAST(RFloat)(obj))
#define RSTRING(obj) (R_CAST(RString)(obj))
#define RREGEXP(obj) (R_CAST(RRegexp)(obj))
#define RARRAY(obj) (R_CAST(RArray)(obj))
#define RHASH(obj) (R_CAST(RHash)(obj))
#define RDATA(obj) (R_CAST(RData)(obj))
#define RSTRUCT(obj) (R_CAST(RStruct)(obj))
#define RBIGNUM(obj) (R_CAST(RBignum)(obj))
#define RFILE(obj) (R_CAST(RFile)(obj))
可是现在呢?
#define R_CAST(st) (struct st*)
#define RBASIC(obj) (R_CAST(RBasic)(obj))
#define ROBJECT(obj) (R_CAST(RObject)(obj))
#define RCLASS(obj) (R_CAST(RClass)(obj))
#define RMODULE(obj) RCLASS(obj)
#define RFLOAT(obj) (R_CAST(RFloat)(obj))
#define RSTRING(obj) (R_CAST(RString)(obj))
#define RREGEXP(obj) (R_CAST(RRegexp)(obj))
#define RARRAY(obj) (R_CAST(RArray)(obj))
#define RHASH(obj) (R_CAST(RHash)(obj))
#define RDATA(obj) (R_CAST(RData)(obj))
#define RTYPEDDATA(obj) (R_CAST(RTypedData)(obj))
#define RSTRUCT(obj) (R_CAST(RStruct)(obj))
#define RBIGNUM(obj) (R_CAST(RBignum)(obj))
#define RFILE(obj) (R_CAST(RFile)(obj))
#define RRATIONAL(obj) (R_CAST(RRational)(obj))
#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
比之前多了TYPEDATA,RATIONAL,COMPLEX三个对象
Ruby 不变的对象
让我们看看结构化的那部分
struct RBasic {
VALUE flags;
const VALUE klass;
}
以及Object
struct RObject {
struct RBasic basic;
union {
struct {
long numiv;
VALUE *ivptr;
struct st_table *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */
} heap;
VALUE ary[ROBJECT_EMBED_LEN_MAX];
} as;
};
还有Rstring
struct RString {
struct RBasic basic;
union {
struct {
long len;
char *ptr;
union {
long capa;
VALUE shared;
} aux;
} heap;
char ary[RSTRING_EMBED_LEN_MAX + 1];
} as;
};
于是让我们回到
对象存在的必要条件
- 能够区分自身与其它(拥有标识)
- 能够响应请求(方法)
- 保持内部状态(实例变量)
struct RBasic {
VALUE flags;
const VALUE klass;
}
这两部分。
- flags是个多目的的标记,大多用以记录结构体的类型。
- klass包含了这个对象归属的类。
最后,让我们看看Float是怎么说的
struct RFloat {
struct RBasic basic;
double float_value;
};
分享到:
相关推荐
关于使用ruby对excel进行操作的内容,比较详细。
一、Ruby的特点与优势 1. 简洁而优雅:Ruby的设计哲学是"最小意外原则",即使代码易于阅读和编写。它使用简洁的语法和优美的表达方式,使得开发人员可以用更少的代码实现更多的功能,提高开发效率。 2. 动态性:...
Ruby的面向对象的枚举
wisper - 一个微型库为Ruby对象提供发布-订阅功能
ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码ruby代码
面向对象的脚本语言Ruby
ruby ,英文资料
MongoMapper - 针对Mongo的一个Ruby对象映射器
这是一本绝对不会让初学者失望的Ruby入门书。 ——Ruby之父 松本行弘 本书为日本公认的最好的Ruby入门教程。 松本行弘亲自审校并作序推荐。 本书支持最新的Ruby 2.0, 也附带讲解了可运行于1.9版本的代码, ...
Her 一个ORM(对象关系映射)将REST资源映射成Ruby对象,它旨在用一个RESTful API代替数据库来构建应用程序。
Ruby三神书之一(其余的两本是Agile.Web.Development.with.Rails和Rails Recipes,在我的资源列表也有) “本书作者曾经教过我很多Ruby知识……每一个从其他语言转到Rais的人都应该拥用本书。为了充分发挥Rails的...
Kashmir是一个Ruby DSL使得序列化和缓存对象易如反掌
Fast JSON API:一个用于Ruby对象的快速JSON:API的序列化器
1993年2月24日是一个值得纪念的日子,在这一天Ruby诞生了。 1995年12月Matz推出了Ruby的第一个版本Ruby 0.95。 在1996年以前,都是Matz.一个人在开发进行Ruby的开发。后来随着Ruby社区的渐渐形成,很多社区成员给了...
第一部分的内容包括对Ruby语言一个概要介绍和对Ruby对象模型的讲解。从我个人阅读的感觉来看,第一章对于Ruby语言的介绍是一个非常好的起步教程,把Ruby语言中一些核心点都指了出来。比起我读到过一些Ruby语言教程,...
《Ruby完全自学手册》是一本完全覆盖Ruby和Ruby on Rails的完全自学手册。《Ruby完全自学手册》的特色是由浅入深、循序渐进,注重理论和实践的结合。虽然定位为入门手册,但是依然涉及许多高级技术和应用,覆盖到的...
本文总结了一些Ruby的使用心得。使用Ruby最需要注意的一点就是效率:因为Ruby执行的效率本身比较慢,所以代码选择很重要。
Ruby,一种简单快捷的面向对象(面向对象程序设计)脚本语言,在20世纪90年代由日本人松本行弘(Yukihiro Matsumoto)开发,遵守GPL协议和Ruby License。它的灵感与特性来自于 Perl、Smalltalk、Eiffel、Ada以及 Lisp ...