千月星跡
アイをも求めて彷徨っている孤独なヒーロー
【免费有礼】欧美最新网络营销技巧分享
博客导入工具
【限时优惠】第五届云计算大会社区门票抢购
探究云计算数据中心节能增效之道 专访邓凡平:Android开发路上的快速学习之道 CSDN博客第二期最佳移动开发博主评选
探究云计算数据中心节能增效之道 专访邓凡平:Android开发路上的快速学习之道 CSDN博客第二期最佳移动开发博主评选
Ruby 基础知识整理
Ruby 是面向 对 象的 编 程 语 言,她追求的是 “ 简 便快捷的面向 对 象 编 程 ” 。 Ruby 是解 释 型 语 言,因此不需 编译 即可快捷地 编 程。同 时 Ruby 具有 类 似 Perl 的 强 大的文本 处 理功能,她可并不只是个玩具,您可以用她来 进 行 实 用的 编 程。此外,您 还 可以很方便地使用 C 语 言来 扩 展 Ruby 的功能,因此可以把她当作各 种库 的前端来使用。
若您曾
经
“
想要一
种简单
的面向
对
象的
语
言
”
,或者
认为
“Perl
的功能
虽
然好用,但它的
语
法真
让
人受不了
”
,又或者
觉
得
“lisp
系列
语
言的思想不
错
,但到
处
都是括号真
让
人
讨厌
,最起
码
算式
应该
按照通常的
样
式
书
写
”
。那
么
,
Ruby
或
许
能
让
您
满
意。
归纳
以来,
Ruby
有以下
优
点。
1
解
释
器
Ruby 是解 释 型 语 言,其程序无需 编译 即可 轻 松 执 行。
2 变 量无 类 型
Ruby 的 变 量没有 类 型,因此不必 为 静 态 的 类 型匹配而 烦恼 。相 应 地, 错误检查 功能也 变 弱了。
3 不需要 变 量声明
所有 变 量均无需声明即可立即使用。另外,从 变 量名即可判断 出是何 种变 量(局部 变 量,全局 变 量, 实 例 变 量)。
Ruby 是解 释 型 语 言,其程序无需 编译 即可 轻 松 执 行。
2 变 量无 类 型
Ruby 的 变 量没有 类 型,因此不必 为 静 态 的 类 型匹配而 烦恼 。相 应 地, 错误检查 功能也 变 弱了。
3 不需要 变 量声明
所有 变 量均无需声明即可立即使用。另外,从 变 量名即可判断 出是何 种变 量(局部 变 量,全局 变 量, 实 例 变 量)。
foo:
局部
变
量
$foo:
全局
变
量
@foo:
类
属性
Foo:
常数
4
语
法
简单
语 法比 较简单 , 类 似 Algol 系 语 法。
5 不需要内存管理
具有垃圾回收( Garbage Collect , GC )功能,能自 动 回收不再使用的 对 象。
6 一切都是 对 象
Ruby 从一 开 始就被 设计 成 纯 粹的面向 对 象 语 言,因此以整数等基本数据 类 型 为 首的所有 东 西都是 对 象,它 们 都有 发 送信息的 统 一接口。
类 , 继 承,方法
Ruby 当然具有面向 对 象 语 言的基本功能。
7 特殊方法
可向某 对 象添加方法。例如,可以把 GUI 按 钮 被按下 时 的 动 作作 为 方法 记 述下来, 还 可以用它来 进 行原型 库 ( prototypebase )的面向 对 象 编 程(有人 这么 干吧)。
用模 块进 行混合插入( Mixin )
Ruby 故意舍弃了多重 继 承,但 拥 有混合插入功能。使用模 块 来超越 类 的界限来共享数据和方法等。
8 迭代器
该 功能可以将循 环 抽象化。
9 闭 包
可以将某 过 程片段 对 象化。 对 象化后的 该过 程片段就称作 闭 包。
10 功能 强 大的字符串操作/正 则 表达式
以 Perl 为样 板 创 造出了功能 强 大的字符串操作和正 则 表达式 检 索功能。
11 拥 有超 长 整数
添加超 长 整数功能后,可以 计 算非常大的整数。例如 计 算 400 的 阶 乘也 轻 而易 举 。
12 具有 错误处 理功能
错误处 理功能可以使您 编 写代 码处 理出 错 情况。
13 可以直接 访问 OS
Ruby 可以使用( UNIX 的) 绝 大部分的系 统调 用。 单 独使用 Ruby 也可以 进 行系 统编 程。
14 动态 加 载
若 OS 支持的 话 ,可以在运行 时读 入 对 象文件。
但 Ruby 也有下列缺点。
15Ruby On Rails , 优 点是不像 Struts 那 样 需要大量的配置文件,一切都采取默 认 的配置,包括 访问 路径, uri 等,而 这 也是它的缺点,不能灵活的配置 。
语 法比 较简单 , 类 似 Algol 系 语 法。
5 不需要内存管理
具有垃圾回收( Garbage Collect , GC )功能,能自 动 回收不再使用的 对 象。
6 一切都是 对 象
Ruby 从一 开 始就被 设计 成 纯 粹的面向 对 象 语 言,因此以整数等基本数据 类 型 为 首的所有 东 西都是 对 象,它 们 都有 发 送信息的 统 一接口。
类 , 继 承,方法
Ruby 当然具有面向 对 象 语 言的基本功能。
7 特殊方法
可向某 对 象添加方法。例如,可以把 GUI 按 钮 被按下 时 的 动 作作 为 方法 记 述下来, 还 可以用它来 进 行原型 库 ( prototypebase )的面向 对 象 编 程(有人 这么 干吧)。
用模 块进 行混合插入( Mixin )
Ruby 故意舍弃了多重 继 承,但 拥 有混合插入功能。使用模 块 来超越 类 的界限来共享数据和方法等。
8 迭代器
该 功能可以将循 环 抽象化。
9 闭 包
可以将某 过 程片段 对 象化。 对 象化后的 该过 程片段就称作 闭 包。
10 功能 强 大的字符串操作/正 则 表达式
以 Perl 为样 板 创 造出了功能 强 大的字符串操作和正 则 表达式 检 索功能。
11 拥 有超 长 整数
添加超 长 整数功能后,可以 计 算非常大的整数。例如 计 算 400 的 阶 乘也 轻 而易 举 。
12 具有 错误处 理功能
错误处 理功能可以使您 编 写代 码处 理出 错 情况。
13 可以直接 访问 OS
Ruby 可以使用( UNIX 的) 绝 大部分的系 统调 用。 单 独使用 Ruby 也可以 进 行系 统编 程。
14 动态 加 载
若 OS 支持的 话 ,可以在运行 时读 入 对 象文件。
但 Ruby 也有下列缺点。
15Ruby On Rails , 优 点是不像 Struts 那 样 需要大量的配置文件,一切都采取默 认 的配置,包括 访问 路径, uri 等,而 这 也是它的缺点,不能灵活的配置 。
语言特征介绍
:
字符串
Ruby将字符串像数字一样处理.我们用单引号('...')或双引号("...")将它们括起来. 单引号和双引号在某些情况下有不同的作用.一个由双引号括起来的字符串允许字符由一个前置的斜杠引出,而且可以用#{}内嵌表达式.而单引号括起来的字符串并不会对字符串作任何解释;你看到的是什么便是什么. 用+把几个串连起来,用*把一个串重复好几遍。
串联: ru
by
>word = "fo" + "o"
"foo"
重复:
word = word * 2
"foofoo"
抽取字符(注意:在Ruby里,字符被视为整数)
:
word[0]
102 # 102 is ASCII code of `f'
word[-1]
111 # 111 is ASCII code of `o'
(负的索引指从字符串尾算起的偏移量,而不是从串头.)
提取子串:
herb = "parsley"
"parsley"
herb[0,1]
"p"
herb[-2,2]
"ey"
herb[0..3]
"pars"
herb[-5..-2]
"rsle"
检查相等:
"foo" == "foo"
true
"foo" == "bar"
false
数组
通过在方括号里列出元素并用逗号将它们相互隔开来创建一个数组。Ruby的数组可以适应不同的对象类型。
ary = [1, 2, "3"]
一. 创建数组:Array.new(
anInteger=0,
anObject=nil )
Array .new | » | [] |
Array .new(2) | » | [nil, nil] |
Array .new(5, "A") | » | ["A", "A", "A", "A", "A"] |
Array .new(2, Hash.new) | » | [{}, {}] |
就像前面提到的字符串一样.数组也可以相乘或相加:
ary + ["foo", "bar"]
[1, 2, "3", "foo", "bar"]
ary * 2
[1, 2, "3", 1, 2, "3"]
我们可用索引来访问数组的任意一部分.
ary[0]
1
ary[0,2]
[1, 2]
ary[0..1]
[1, 2]
ary[-2]
2
ary[-2,2]
[2, "3"]
ary[-2..-1]
[2, "3"]
(负数索引表示到数组末尾的偏移,而不是从开头算起.)
数组可以和字符串互相转化,分别使用join和split:
str = ary.join(":")
"1:2:3"
str.split(":")
["1", "2", "3"]
哈希表
一个关联数组不通过连续的数字索引来访问,而是通过任何类型的主键(key)访问.这样的数组有时被叫作哈希(hash)或者字典(dictionary).在Ruby里,我们趋向于用哈希这个术语.将一对对的元素用逗号分隔开,并用大括号({})括起来,这样就组成了一个哈希表.你用一个关键字在哈希表里进行搜索,就像你在数组里用索引来提取数据一样.
h = {1 => 2, "2" => "4"}
{1=>2, "2"=>"4"}
h[1]
2
h["2"]
"4"
h[5]
nil
h[5] = 10 # appending value
10
h
{5=>10, 1=>2, "2"=>"4"}
h.delete 1 # deleting value
2
h[1]
nil
h
{5=>10, "2"=>"4"}
流程控制
条件控制语句
一.If语句
二.Case语句
循环控制语句
三.Loop语句
四.While语句
五.For语句
第一,和C一样
break从循环中完全退出.第二,
next 跳到下一次循环迭代的开始(对应于C的
continue ).第三,Ruby有
redo,它可以重新开始现在的迭代. 第四种方法是由循环内跳出的方法是
returen. return的结果是不仅从循环中跳出,而且会从含循环的方法中跳出.如果有参数,它会返回给方法调用,不然就返回
nil.
迭代器
Ruby的
String类型有很多有用的迭代器:
"abc".each_byte{|c| printf "<%c>", c}; print "/n"
<a><b><c>
each_byte 是个用于字符串中每个字符的迭代器.每个字符串由局部变量c代替.
String的另一个迭代器是
each_line.
"a/nb/nc/n".each_line{|l| print l}
a
b
c
可以用
retry
流程控制语句连接迭代循环,它会从头执行当前循环的迭代.
c=0
for i in 0..4
print i
if i == 2 and c == 0
c = 1
print "/n"
retry
end
end; print "/n"
012
01234
yield
有时会在一个迭代器的定义中出现.
yield将流程控制移至传递给迭代器的代码域。下面的例子定义了一个
repeat迭代器,会依参数的设置执行多次代码域。
def repeat(num)
while num > 0
yield
num -= 1
end
end
repeat(3) { print "foo/n" }
foo
foo
foo
类
在Ruby里,一个类的定义是在关键字
class和
end之间的一段代码.在域中的def开始定义类的一个
方法,它对应于此类中中的某些特定的对象方法.
class Dog
def speak
print "Bow Wow/n"
end
end
既然我们已有了
Dog类,我们就可以用它来创造一只狗:
pochi = Dog.new
pochi.speak
继承和重载
class Bird
def preen
print "I am cleaning my feathers."
end
def fly
print "I am flying."
end
end
class Penguin<Bird
def fly
fail "Sorry. I'd rather swim."
end
end
在子类里,我们可以通过重载父类方法来改变实体的行为.
class Human
| def identify
| print "I'm a person./n"
| end
| def train_toll(age)
| if age < 12
| print "Reduced fare./n";
| else
| print "Normal fare./n";
| end
| end
| end
nil
ruby> Human.new.identify
I'm a person.
nil
ruby> class Student1<Human
| def identify
| print "I'm a student./n"
| end
| end
nil
ruby> Student1.new.identify
I'm a student.
如果我们只是想增强父类的
identify 方法而不是完全地替代它,就可以用
super.
class Student2<Human
| def identify
| super
| print "I'm a student too./n"
| end
| end
nil
ruby> Student2.new.identify
I'm a human.
I'm a student too.
super 也可以让我们向原有的方法传递参数.
class Dishonest<Human
| def train_toll(age)
| super(11) # we want a cheap fare.
| end
| end
nil
ruby> Dishonest.new.train_toll(25)
Reduced fare.
nil
ruby> class Honest<Human
| def train_toll(age)
| super(age) # pass the argument we were given
| end
| end
nil
ruby> Honest.new.train_toll(25)
Normal fare.
当我们在"最高层"而不是在一个类的定义里定义一个方法时会发生什么.
def square(n)
| n * n
| end
nil
ruby> square(5)
25
我们的新方法看起来不属于任何类,但实际上Ruby将其分给
Object类,也就是所有其它类的父类.因此,所有对象现在都可以使用这一方法.这本应是正确的,但有个小陷阱:它是所有类的
私有(private)方法.我们将在下面讨论这是什么意思,但一个结果是它只能以函数的风格调用,像这样:
class Foo
| def fourth_power_of(x)
| square(x) * square(x)
| end
| end
nil
ruby> Foo.new.fourth_power_of 10
10000
我们不允许向一个对象明确地运用这一方法:
"fish".square(5)
ERR: (eval):1: private method `square' called for "fish":String
私有方法
class Test
| def times_two(a)
| print a," times two is ",engine(a),"/n"
| end
| def engine(b)
| b*2
| end
| private:engine # this hides engine from users
| end
Test
ruby> test = Test.new
#<Test:0x4017181c>
ruby> test.engine(6)
ERR: (eval):1: private method `engine' called for #<Test:0x4017181c>
ruby> test.times_two(6)
6 times two is 12.
为实例添加新的方法
实例的行为取决于其类,但很多时候我们知道一个特定的实体需要特定的行为.在很多语言里,我们必须陷入另外再定义一个类的麻烦里,即使它只是用来接着实体化一次.在Ruby里,我们可以赋予任何对象属于其自身的方法.
class SingletonTest
| def size
| print "25/n"
| end
| end
nil
ruby> test1 = SingletonTest.new
#<SingletonTest:0xbc468>
ruby> test2 = SingletonTest.new
#<SingletonTest:0xbae20>
ruby> def test2.size
| print "10/n"
| end
nil
ruby> test1.size
25
nil
ruby> test2.size
10
在这个例子里,
test1和
test2属于相同的类,但
test2已被赋给一个重载的
size方法,因而他们有不同的行为.一个仅属于某个对象的方法叫做
单态方法.
单态方法常常用于图形用户界面(GUI)的元素的设计,在那里当不同的按钮被压下时将会激发不同的事件.
模块
Ruby的模块非常类似类,除了:
l
模块不可以有实体
l
模块不可以有子类
l
模块由
module...end定义.
实际上...模块的'模块类'是'类的类'这个类的父类.搞懂了吗?不懂?让我们继续看下去吧.
模块有两种用法.其一是将相近的方法和实体放在一个相对集中的域里.Ruby标准包里的Math模块就扮演着这一角色:
Math.sqrt(2)
1.41421
ruby> Math::PI
3.14159
::操作符告诉 Ruby 解释器在哪里找常数的值(可以想像,
Math外的其它模块用
PI表示其它的一些东西).如果我们想省掉 :: 直接调用一个模块的方法和常数,我们可以用
include:
include Math
Object
ruby> sqrt(2)
1.41421
ruby> PI
3.14159
模块的另一用法是
糅和(mixin).某些OO语言,包括C++,允许
多重继承(multiple inheritance),即从多个的父类里继承. 现实世界里一个多重继承的
例子是闹钟:你可以想像闹钟属于 钟类同是属于 带蜂音器的事物类.
例子是闹钟:你可以想像闹钟属于 钟类同是属于 带蜂音器的事物类.
Ruby并未特意实现真正的多重继承,但 糅和技术是一很好的替代.记得模块无法实体化或子类化;但如果我们在类定义里 include一个方法,
它的方法便实际上已加入,或"糅合"进这个类.
糅合可以视为一种寻求一切我们希望得到的特定属性的方法.举个例子,如果一个类有个 each 方法,把标准库里的 Enumerable模块糅合进来就自然地赋予我们 sort 和 find 两个方法.
模块的使用令到我们获得多重继承的基本功能却可通过简单的树结构表述类关系,同时也可观地简化了语言的实现(Java的设计者也做了一个类似的选择).
过程对象
我
们总
是希望
对
未知事件分
类
.
当它
发
生
时
,
向其它方法
传递
一
块
作
为
参数的代
码
是最容易地解决方法
,
也就是
说
我
们
希望像
处
理数据一
样处
理代
码
.
一个新的 过程对象 可以通 过 proc 创 建 :
ruby> quux = proc { | print "QUUXQUUXQUUX!!!/n" | } #<Proc:0x4017357c> |
现 在 quux 指向一个 对 象 , 像其它 对 象一 样 , 它也有可以 调 用的行 为 . 特 别 的 , 我 们 可以用 call 方法 执 行它 :
ruby> quux.call QUUXQUUXQUUX!!! nil |
那 么 quux 可以用做一个方法的参数 吗 ? 当然 .
ruby> def run( p ) | print "About to call a procedure.../n" | p.call | print "There: finished./n" | end nil ruby> run quux About to call a procedure... QUUXQUUXQUUX!!! There: finished. nil |
trap 方法令到我 们 可以 对 任何系 统 信号做出我 们 自己的 选择 .
ruby> inthandler = proc{ print "^C was pressed./n" } #<Proc:0x401730a4> ruby> trap "SIGINT", inthandler #<Proc:0x401735e0> |
一般的 , 敲入 ^C 将 导 致解 释 器退出 . 但 现 在一个信息被打印出来 , 解 释 器 继续执 行着 , 所以你不会 丢 失掉正在作 业 的工作 .( 你不会永 远 留在解 释 器里 , 你仍可以用 exit 或者按 ^D 退出 )
最后在我
们开
始下一
节
之前
还应
注意的一点是
:
在将一个
过
程
对
象捆
绑
到一个信号之前
,
不是必
须给这
个
过
程
对
象命名的
.
一个等效的匿名
(anonymous)
过
程
对
象像
这样
ruby> trap "SIGINT", proc{ print "^C was pressed./n" } nil |
或着更 简 略,
ruby> trap "SIGINT", 'print "^C was pressed./n"' nil |
这种简 写 为 你提供了一 种 方便和可 读 性更 强 的写小匿名 过 程的路子 .
变量
Ruby有三类变量,一种常量和两种严格意义上的
伪变量(pseudo-variables).变量和常量都没有类型。在Ruby里我们不需要变量声明。
由首字母
标识
符将其分
类
:
$ | 全局变量 |
@ | 实变量 |
[a-z] or _ | 局部变量 |
[A-Z] | 常量 |
唯一的例外是Ruby的
伪变
量:
self
,它永
远
指向当前正
执
行着的
对
象或未初始化
变
量的空
值
(meaningless value)
nil
.
虽
然
这
两者的命名都像是局部
变
量,但
self
却是个由解
释
器把持的全局
变
量,而
nil
实际
上是个常量.既然只有
这
两
种
意外,他
们
并不会
过
多的干
扰
我
们
.
你并能向
self
或
nil
赋值
.下面的例子中,
main
作
为
self
的
值
,指向最高
层
的
对
象:
ruby> self main ruby> nil nil |
全局变量
全局
变
量由
$
开头
.
它
们
可以在程序的任何位置
访问
到
.
在初始化前
,
全局
变
量有一个特殊的
值
nil
.
ruby> $foo nil ruby> $foo = 5 5 ruby> $foo 5 |
应谨 慎使用全局 变 量 . 由于在任何地方都可以被写因此他 们 相当危 险 . 滥 用全局 变 量会 导 致很 难 隔离臭虫 ; 同 时 也 视为 程序的 设计 未 经严 格考 虑 . 当你 发现 必 须 要使用全局 变 量 时 , 记 得 给 它一个不会在其它地方一不小心就用到的描述性名字 ( 像上面那 样 叫 $foo 可能不是一个好想法 ).
全局 变 量的好 处 是其可以被跟踪 ; 你可以做一个当 变 量 值 改 变时 被 调 用的 过 程 .
ruby> trace_var :$x, proc{print "$x is now ", $x, "/n"} nil ruby> $x = 5 $x is now 5 5 |
当一个全局
变
量
(
改
变时
)
作
为
一个
过
程的激
发
器
,
我
们
也管它叫活
动变
量
(active variable).
比如
说
,
它可用于保持
GUI
显
示的更新
.
这 里列出了一些以 $ 打 头 并跟 单 个字符的特殊 变 量 . 比如 ,$$ 包含了 Ruby 解 释 器的 进 程 id, 它是只 读 的 . 这 里是主要的系 统变 量以及它 们 的含 义 ( 细节 可在 Ruby 的 参考手册 中 查 到 ):
$! | 最近一次的错误信息 |
$@ | 错误产生的位置 |
$_ | gets最近读的字符串 |
$. | 解释器最近读的行数(line number) |
$& | 最近一次与正则表达式匹配的字符串 |
$~ | 作为子表达式组的最近一次匹配 |
$ n | 最近匹配的第n个子表达式(和$~[n]一样) |
$= | 是否区别大小写的标志 |
$/ | 输入记录分隔符 |
$/ | 输出记录分隔符 |
$0 | Ruby脚本的文件名 |
$* | 命令行参数 |
$$ | 解释器进程ID |
$? | 最近一次执行的子进程退出状态 |
上面的 $_ 和 $~ 都有作用范 围 . 它 们 的名字暗示其 为 全局的 , 但它 们 一般都是 这样 用的 , 关 于它 们 的命名有 历 史上的原因 .
实变量
一个
实变
量由
@
开头
,
它的范
围
限制在
self
对
象内
.
两个不同的
对
象
,
即使属于同一个
类
,
也可以
拥
有不同
值
的
实变
量
.
从
对
象外部来看
,
实变
量不能改
变
甚至
观
察
(
比如
, Ruby
的
实变
量从来不是公用的
),
除非方法由程序
员
明确声明
.
像全局
变
量一
样
,
实变
量在初始前的
值
是
nil
.
Ruby 的 实变 量用不着声明 . 这 暗含着 对 象的 弹 性 结 构 . 实际 上 , 每 个 实变 量都是在第一次出 现时动态 加入 对 象的 .
ruby> class InstTest | def set_foo(n) | @foo = n | end | def set_bar(n) | @bar = n | end | end nil ruby> i = InstTest.new #<InstTest:0x83678> ruby> i.set_foo(2) 2 ruby> i #<InstTest:0x83678 @foo=2> ruby> i.set_bar(4) 4 ruby> i #<InstTest:0x83678 @foo=2, @bar=4> |
注意上例中直到 调 用了 set_bar 方法 i 才 报 告 @bar 的 值 .
局部变量
局部
变
量由小写字母或下划
线
(_)
开头
.
局部
变
量不像全局和
实变
量一
样
在初始化前含
nil
值
.
ruby> $foo nil ruby> @foo nil ruby> foo ERR: (eval):1: undefined local variable or method `foo' for main(Object) |
对 局部 变 量的第一次 赋值 做的很像一次声明 . 如果你指向一个未初始化的局部 变 量 ,Ruby 解 释 器会 认为 那是一个方法的名字 ; 正如上面所 见错误 信息的 .
一般的
,
局部
变
量的范
围
会是
- proc{...}
- loop{...}
- def...end
- class...end
- module...end
- 整个程序(除非符合上面某个条件)
下面的例子 , define? 是一个 检查标识 符是否已定 义 的操作符 . 如果已定 义 它将返回 标识 符的描述 , 否 则 返回 nil . 正如你所 见 的 , bar 的范 围 是 loop 的局部 变 量 ; 当 loop 退出 时 , bar 无定 义 .
ruby> foo = 44; print foo, "/n"; defined? foo 44 "local-variable" ruby> loop{bar=45; print bar, "/n"; break}; defined? bar 45 nil |
一个范 围 内的 过 程 对 象共享 这 个范 围 内的局部 变 量 . 这 里 , 局部 变 量 bar 由 main 和 过 程 对 象 p1, p2 共享 :
ruby> bar=0 0 ruby> p1 = proc{|n| bar=n} #<Proc:0x8deb0> ruby> p2 = proc{bar} #<Proc:0x8dce8> ruby> p1.call(5) 5 ruby> bar 5 ruby> p2.call 5 |
注意 开 始的 " bar=0 " 不能省略 ; 此 赋值 允 许 bar 的范 围 被 p1 和 p2 共享 . 不然 p1, p2 将会分 别 生成并 处 理它 们 自己的局部 变 量 bar , 调 用 p2 也将 导 致 " 未定 义 局部 变 量或方法 " 错误 .
过 程 对 象的 强 大在于它 们 能被作 为 参数 传递 : 共享的局部 变 量即使 传递 出原范 围 也仍然有效 .
ruby> def box | contents = 15 | get = proc{contents} | set = proc{|n| contents = n} | return get, set | end nil ruby> reader, writer = box [#<Proc:0x40170fc0>, #<Proc:0x40170fac>] ruby> reader.call 15 ruby> writer.call(2) 2 ruby> reader.call 2 |
Ruby 对 待范 围 的 办 法相当 聪 明. 显 然,上面例子里 contents 变 量是由 reader 和 writer 共享的.我 们 也可以像上面那 样创 造多 对 使用 box 的 reader-writer ; 每 一 对 共享一个 content s 变 量, 对 之 间 不相干 扰 .
ruby> reader_1, writer_1 = box [#<Proc:0x40172820>, #<Proc:0x4017280c>] ruby> reader_2, writer_2 = box [#<Proc:0x40172668>, #<Proc:0x40172654>] ruby> writer_1.call(99) 99 ruby> reader_1.call 99 ruby> reader_2.call 15 |
类常量
一个常量由大写字母
开头
.
它
应
最多被
赋值
一次
.
在
Ruby
的当前版本中
,
常量的再
赋值
只会
产
生警告而不是
错误
(non-ANSI
版的
eval.rb
不会
报
告
这
一警告
)
ruby>fluid=30 30 ruby>fluid=31 31 ruby>Solid=32 32 ruby>Solid=33 (eval):1: warning: already initialized constant Solid 33 |
常量可以定
义
在
类
里
,
但不像
实变
量
,
它
们
可以在
类
的外部
访问
.
ruby> class ConstClass | C1=101 | C2=102 | C3=103 | def show | print C1," ",C2," ",C3,"/n" | end | end nil ruby> C1 ERR: (eval):1: uninitialized constant C1 ruby> ConstClass::C1 101 ruby> ConstClass.new.show 101 102 103 nil |
常量也可以定
义
在模
块
里
.
ruby> module ConstModule | C1=101 | C2=102 | C3=103 | def showConstants | print C1," ",C2," ",C3,"/n" | end | end nil ruby> C1 ERR: (eval):1: uninitialized constant C1 ruby> include ConstModule Object ruby> C1 101 ruby> showConstants 101 102 103 nil ruby> C1=99 # not really a good idea 99 ruby> C1 99 ruby> ConstModule::C1 # the module's constant is undisturbed ... 101 ruby> ConstModule::C1=99 ERR: (eval):1: compile error (eval):1: parse error ConstModule::C1=99 ^ ruby> ConstModule::C1 # .. regardless of how we tamper with it. 101 |
异常处理:
当一个方法
结
束工作
时
我
们
也
许
需要
进
行清理工作
.
也
许
一个打
开
的文件需要
关闭
,
缓
冲区的数据
应
清空等等
.
如果
对
于
每
一个方法
这
里永
远
只有一个退出点
,
我
们
可以心安理得地将我
们
的清理代
码
放在一个地方并知道它会被
执
行
;
但一个方法可能从多个地方返回
,
或者因
为
异常我
们
的清理代
码
被意外跳
过
.
begin
file = open("/tmp/some_file", "w")
# ... write to the file ...
file.close
rescue
file.close
fail # raise an exception
end
file = open("/tmp/some_file", "w")
# ... write to the file ...
file.close
rescue
file.close
fail # raise an exception
end
在Ruby里,就像其它的现代语言,我们可以通过隔离的办法处理代码域里的异常,因此,这有着惊人的效果却又不会为程序员或以后希望读它的其它人造成过度的负担.代码域由begin开始直到遇到一个异常,这将导致转向一个由rescue标记的错误处理代码域.如果异常没发生,rescue代码就不会使用.下面的代码返回文本文件的第一行,如果有异常则返回 nil.
- 上一篇:Command模式
- 下一篇:(整理)RUBY的CGI访问
-
5楼
youyang1991 2011-07-15 17:12发表
-
- so useful !!!
-
4楼
youyang1991 2011-07-15 14:58发表
-
- 大谢楼主了!
-
3楼
Duallay 2011-06-20 13:54发表
-
- 言简意赅,好,顶一个!
-
2楼
GreenLearner 2009-11-03 20:32发表
-
-
ruby> var = " abc "
" abc "
ruby> "1234#{var}5678"
ERR:undefined local variable or method 'var' for main:Object
这个错误是什么原因啊,怎么改正这个错误呢?
-
1楼
GreenLearner 2009-11-03 16:08发表
-
-
ruby> var = " abc "
" abc "
ruby> "1234#{var}5678"
ERR:undefined local variable or method 'var' for main:Object
- 个人资料
-
- 访问:158409次
- 积分:4154分
- 排名:第1138名
- 原创:230篇
- 转载:137篇
- 译文:8篇
- 评论:22条
- 文章搜索
- 文章分类
- 阅读排行
- (9965)
- (4899)
- (2116)
- (1987)
- (1973)
- (1799)
- (1795)
- (1769)
- (1709)
- (1580)
- 评论排行
- (5)
- (2)
- (2)
- (2)
- (1)
- (1)
- (1)
- (1)
- (1)
- (1)
- 推荐文章
- 最新评论
: 好不赖,多谢
: 谢谢分享!请问这样的代码是怎么贴上去的啊?
: 果断关注了~
: 能给我讲下remove_copy_if泛型算法吗?不懂
: so useful !!!
: 大谢楼主了!
: 言简意赅,好,顶一个!
:
: 您好,请问 _DEBUG_RANGE(_First1, _Last1); _DEBU...
: