参考手册:Ruby 语言样式——执行
php?name=Ruby" onclick="tagshow(event)" class="t_tag">Ruby 程序
Ruby程序的执行就是对代码进行计算的过程。先编译程序文本,遇到BEGIN就对其作出计算;然后计算顶层的一系列的表达式;若遇到END的话,将在最后对其进行处理然后结束程序(关于结束程序时处理步骤的详细过程请参考结束程序时的相关处理)。
语句
if
if句的计算过程如下:先对条件表达式进行计算,若为真则执行相应代码段,若为假则依次计算elseif部分的条件表达式,若遇到值为真的表达式则执行相应的代码段。若所有的条件表达式的值都为假的话,就执行else部分的代码段。
语句的值取决于最后执行的代码块的值。若最后的代码块中没有表达式,或者所有条件表达式的值都是假而且没有else部分的话,则语句的值为nil。
until
if 修饰部分
unless 修饰部分
while
until
while 修饰部分
until 修饰部分
for
begin ~ end
类定义句
定义类的内容。在执行时(而并非编译时)进行计算。
书写样式
class ClassName [< 超类表达式]
表达式
end
在对类定义句进行计算时,将先试图生成类。若有超类表达式就加以计算,其值作为ClassName类的父类,然后生成ClassName类的实例.若没有超类表达式,就把Object作为其父类.
另一方面,若有同名类的话,就先使用那个同名类。然后处理超类表达式,若新生成的超类(在equal?)有所不同的话,就再生成一个新的类。
得到类之后就将其代入常数“ClassName”中,由此决定类名。此时,若同名的常数中被代入一个非Class的实例的话,就会引发异常TypeError。
最后生成新的框架(frame),向顶层块的self以及class设定要进行定义的类,然后在框架的基础上对定义句中的表达式进行计算。我们无法得到类定义句的值。
也就是说,在Ruby中我们可以多次“追加类定义”。
模块定义句
定义模块的内容。在执行时(而并非编译时)进行计算。
书写样式
module ModuleName
模块内容
end
对模块定义句进行计算时,首先会生成新的无名模块。但是,若已经有了一个名为ModuleName的模块的话,就使用该模块。此时就变成“追加模块的定义”了。
得到模块后就将其代入常数ModuleName中。这个常数就成为模块的名称。此时,若向同名常数代入非模块的话就会引发异常TypeError。
最后生成新的框架(frame),向顶层块的self以及class中设定模块ModuleName,然后在框架的基础上对定义句中的表达式进行计算。模块定义句的值就是模块内容的最后一个表达式的值。若模块内容中没有可计算的表达式时,其值为nil。
特殊类定义句
定义对象的特殊类。在执行时(而并非编译时)进行计算。
书写样式
class << EXPR
类的内容
end
先计算想定义特殊类的对象的表达式EXPR。然后生成该对象的特殊类(若尚未生成的话)。最后生成新框架,向顶层块的self和class中设定新生成的特殊类。在新框架的基础上对定义句中的表达式进行计算。
特殊类定义句的值取决于类的内容中的最后一个表达式的值。若没有可计算的表达式时,其值为nil。
请注意,Fixnum Symbol的实例以及 true false nil 不能定义特殊类
方法定义句
定义方法的内容。在执行时(而并非编译时)进行计算。
书写样式
def method_name(arg, argwithdefault=expr, *restarg, &block)
方法内容
end
对其进行计算时,将向运行块的class中定义该方法。若class中已经存在同名的方法的话,则抛弃旧方法,添加新方法。
方法定义句的值为nil。
特殊方法定义句
向对象的特殊类中定义方法。在执行时(而并非编译时)进行计算。
书写样式
def expr.method_name(arg, argwithdefault=expr, *restarg, &block)
方法内容
end
首先计算表达式expr。然后生成对象的特殊类(若尚未生成的话)。最后向特殊类中定义方法method_name。
特殊方法定义句的值为nil。
请注意,Fixnum Symbol的实例以及true false nil不能定义特殊方法。
BEGIN
编译时会用到(执行时首先计算)
END
编译时会用到(执行时最后计算)
方法
方法的调用
首先计算被调(receiver)表达式,得到被调用对象。省略被调表达式时,调用块的self将成为被调。
接下来从左到右地对参数表达式进行计算,检索被调里面的方法。若检索失败则引发异常NameError,成功的话就执行方法。
另外,执行方法的时候还可以添加块(block)。若向方法添加块时,只有当运行中的方法执行yield时才会对块进行计算。若没有执行yield的话,块将被忽视,不会执行。
将块传给方法时,该块将会继承调用方的块的self和class。只有Module#module_eval/class_eval和Object#instance_eval这三个例外,如下所示。
Module#module_eval, class_eval
self和class都是被调(receiver)
Object.instance_eval
self是被调,class是被调的特殊类