Ruby简介:语法与运行过程

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

14
语法解析 Parsing
15
• 语法解析阶段,Ruby会将词条文本转换成“抽象语法树”(abstract syntax tree),简称AST。 • “抽象语法树”是程序在内存中的表现形式。
require 'ripper'
require 'pp' pp Ripper.sexp("x > 100 ? 'foo' : 'bar'") # [:program,
Ruby的其他亮点
• Ruby中类和模块是不封闭的。 • 模块和类都是动态调用的。
11
• Ruby支持正则表达式。
• Ruby有强大的库。 • Ruby的大部分操作都在操作系统层之下, • Ruby的另一个显著特点是允许对象的特殊化, • Ruby内置了废料收集,使用mark一and一sweep算法。
BEGIN {
# BEGIN 代码块 puts "BEGIN 代码块" } END { # END 代码块 puts "END 代码块" } # MAIN 代码块 puts "MAIN 代码块"
运行结果: BEGIN 代码块 MAIN 代码块
END 代码块
模块(Module)
模块(Module)是一种把方法、类和常量组合在一起 的方式。模块(Module)提供了两大好处。
19
# 0005 putobject
# 0007 opt_gt # 0009 branchunless # 0011 putstring
100
<callinfo!mid:>, argc:1, ARGS_SIMPLE> 15 "foo"
# 0013 leave
# 0014 pop # 0015 putstring # 0017 leave "bar"
Ripper.tokenize("x > 1 ? 'foo' : 'bar'")
# => ["x", " ", ">", " ", "1", " ", "?", " ", "'", "foo", "'", " ", ":", " ", "'", "bar", "'"]
词法解析 Lexing
require 'ripper' require 'pp' pp Ripper.lex("x > 100 ? 'foo' : 'bar'") # [[[1, 0], :on_ident, "x"], # [[1, 1], :on_sp, " "], # [[1, 2], :on_op, ">"], # [[1, 3], :on_sp, " "], # [[1, 4], :on_int, "100"], # [[1, 5], :on_sp, " "], # [[1, 6], :on_op, "?"], # ……
Ruby程序解释与运行
Ruby是一门解释性语言
• Ruby程序执行流程:
• • • • • 分词 词法解析 语法解析 编译成字节码 Ruby VM执行
12
分词 Tokenizing
将程序代码切分成块(chunks),被称之为词条(token)
13
x > 100 ? 'foo' : 'bar'
require 'ripper'
9
Ruby include语句
Ruby可以在类中嵌入模块。为了在类中嵌入 模块,可以在类中使用include语句。 在include一个模块时,该模块中的方法就会 附加到这个类中,这就是mix一in。 这几乎消除了多重继承的需要
10
Array也可以include其他模块来扩充自己, 模块Enumerable也可以mix一in到其他类中。 这就有效地解决了多重继承问题,使Ruby可以得 到多重继承的效果,同时又避免了多重继承所造成 的麻烦。

5
Ruby类之间只允许单继承,未指明父类的都是 Object类的子类。 在第20行建立了一个People的对象smith,建立对 象时只调用从类Objcet继承的默认方法new。new 为对象分配空间,然后调用方法initialize,并将自 己的参数传递给它。 可以认为initialize等价于C++或者Java中的构造函 数。introduee是为People类添加的一个方法,如 果需要还可以添加其他方法。 People的子类Adult继承了People的两个方法。其 中完全重新定义了方法introduce。 继承父类的方法时,可以选择是对其进行补充,还 是完全覆盖。 如这里继承方法initialize的时候没有重新写,而是 通过方法super执行父类方法,然后做了些补充。
18
字节码编译 Compiling to bytecode
puts RubyVM::InstructionSequence.compile("x > 100 ? 'foo' : 'bar'").disassemble # == disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>========== # 0000 trace # 0002 putself # 0003 opt_send_without_block <callinfo!mid:x, argc:0, FCALL|VCALL|ARGS_SIMPLE> 1 ( 1)
4
我们可以在Ruby中编写以下表达式:
“HelloWorld“.length -1979.abs
表达式计算将得到如下结果:
11 1979
Ruby中所有的方法调用都是给对象传递消息。 Ruby用“.”号分隔对象和消息,位于”.”前面的被当作对象,也 就是消息的接收者;“.“后面的就是传递给对象的消息。
语法解析 ParsFra Baidu bibliotekng
# 定义程序
16
[:program,
# if比较 [[:ifop, # 条件检测 (x > 100) [:binary, [:vcall, [:@ident, "x", [1, 0]]], :>, [:@int, "100", [1, 4]]], # 若为true,则返回“foo” [:string_literal, [:string_content, [:@tstring_content, "foo", [1, 11]]]], # 若为false,则返回“bar ” [:string_literal, [:string_content, [:@tstring_content, "bar", [1, 19]]]]]]]
Ruby的实例变量只能在类或子类内部使 用,外部不能直操作它们。 这相当于C++类中具有protected属性的 成员。 要想读写这些变量,就需要写出类的属性 方法,类似于set和get函数。 例如,我们可以如下定义@name的属性 函数
块(Block)
Ruby提供了一套技术,通过它们可以建立一 套独立的控制结构或者一段独立代码,并将 其打包,做成独立的可重复使用的对象。 块总是从与其具有相同名称的函数调用。这 意味着如果您的块名称为test,那么您要使 用函数test来调用这个块。
• Matz, Koichi访谈(一): Ruby虚拟机
THANK YOU!
从MRI到YARV
以遍历整个AST(抽象语法树)的方式执行程序
17
• Ruby 1.9之前,Ruby的官方解释器是Matz’s Ruby Interpreter(MRI), • Ruby 1.9之后,YARV(Yet Another Ruby VM)取代MRI,作为Ruby执 行程序的解释器 • YARV将抽象语法树进一步编译成字节码来运行,同时针对一些特殊指令有 大量的优化
Ruby简介:语法与运行过程
Ruby语言语法
3
Ruby简介
• Ruby是一种纯粹的面向对象脚本语言。它由日本的松本行 弘创建于1983年。 • 他常说,他是“试着让Ruby更自然,而不是更简单”,让 一切符合生活常规。
真正的面向对象语言
在Ruby里,程序操作的一切都是对象,产生的结果也都是对象。
• 模块提供了一个命名空间和避免名字冲突。
• 模块实现了mix-in装置。 模块(Module)定义了一个命名空间,相当于一个沙 盒,在里边您的方法和常量不会与其他地方的方法常 量冲突。 模块类似与类,但有以下不同: • 模块不能实例化 • 模块没有子类 • 模块只能被另一个模块定义
定义一个模块: module Trig PI = 3.141592654 def Trig.sin(x) # .. End def Trig.cos(x) # .. End end
7
使用一个简单的 yield 语句来调用块: def test yield 5 puts "在 test 方法内“ yield 100 end test {|i| puts "你在块 #{i} 内"}
运行结果: 你在块 5 内 在 test 方法内 你在块 100 内
8
BEGIN和END块
每个Ruby源文件可以声明当文件被加载时要运行的代码块(BEGIN块),以及程序完成执 行后要运行的代码块(END块)。
# [[:ifop,
# # # [:binary, [:vcall, [:@ident, "x", [1, 0]]], :>, [:@int, "100", [1, 4]]], [:string_literal, [:string_content, [:@tstring_content, "foo", [1, 11]]]], [:string_literal, [:string_content, [:@tstring_content, "foobar", [1, 19]]]]]]]
6
所有变量都是对象的引用,变量赋值不是 对象复制,而是引用的传递
Ruby采用一套命名规则区分变量的性质。 用首字母表示这个名字的作用。 局部变量、方法参数及方法名都由小写字母 或下划线开头; 全局变量由美元符号”$’`开头; 实例变量开始于“@”; 类变量由”@@“开始;类名、模块名以及常 量都用大写字母开头
20
REFERENCE
• 张欣,隗刚,裘宗燕;《初识Ruby语言》 • Ruby 教程,http://www.runoob.com/ruby/ruby-tutorial.html • 关于 Ruby,http://www.ruby-lang.org/zh_cn/about/
• Starr Horne,How Ruby Interprets and Runs Your Programs
相关文档
最新文档