设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
楼主: DeathKing
打印 上一主题 下一主题

[讨论] Ruby/RGSS Tips 每日一更 [技术区的版聊帖?]

  [复制链接]

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
12
发表于 2010-9-4 22:45:33 | 只看该作者
2010-09-04 不常见的字面值及 Shell 命令表示法
Ruby 支持的字面值和 Shell 命令表示法很多样化,我们最常用的是:
1、双引号字符串,如 "hello\nworld",支持转义字符和内嵌表达式
2、单引号字符串,如 'hello world',原始字符串数据,不支持转义字符和内嵌表达式(在不需要这两者的时候尽量用单引号提高效率)
3、正斜杠正则表达式,如 /regex/i
4、反引号 Shell 命令,如 `pause`
除此之外,Ruby 还支持所有 Unix Shell 以及大部分脚本语言都支持的 Here document,能够方便地进行多行的字符串输入:

  1. str = <<DELIMETER
  2. 桑之未落
  3. 其叶沃若
  4. 桑之落矣
  5. 其黄而陨
  6. DELIMETER
  7. p str
复制代码
如果你用过字幕脚本,你就会觉得这段脚本很熟悉,因为字幕脚本用的也是 here document。DELIMITER 是自定义的分隔符,在两个分隔符(这里是两个 DELIMITER)之间的内容会被认为是字符串输入。不过这样写的 here document 不能进行缩进,强行缩进的话,最后的 DELIMETER 处会发生语法错误。在 << 后加上短横线 - 就可以解决:
  1. if true
  2.   str = <<-DELIMETER
  3.   桑之未落
  4.   其叶沃若
  5.   桑之落矣
  6.   其黄而陨
  7.   DELIMETER
  8.   p str
  9. end
复制代码
Ruby 还有所谓的常规定界输入(General delimited input),使得字符串、正则表达式、字元数组和 Shell 命令有了额外的表示法:
%q{这相当于一个单引号字符串}
%Q{这相当于一个双引号字符串}
%{这相当于一个单引号字符串}
%w{这 是 一 个 字 元 数 组 , 字 元 以 空 白 符 分 隔}
%r{[0-9]+} # 正则表达式
%x{mspaint} # Shell 命令
其中 `{' 和 `}' 是用来表示该输入的开始和结束的,也可以用其它分隔符表示,如
%#这是一个双引号字符串# # 这前面可不是注释哦,虽然 RGSS 的编辑器将它当做注释高亮显示了,或者两两对应的字符, `(' 和 `)',`[' 和 `]',以及 `<' 和 `>'
常规定界输入也支持多行输入,%q 和 % 使用起来比 here document 还方便!

点评

比较喜欢Here文档,电脑显示器除了点问题,这个帖子就要指望老板了。  发表于 2010-9-5 14:57
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
11
发表于 2010-9-3 12:46:58 | 只看该作者
2010-09-03 冗余代码

所谓冗余,是指没有意义、永远不会被执行的代码,或多次运算且结果相同的不必要代码。前两者很容易理解,这里我们主要说一下“多次运算的结果相同的不必要代码”。这种冗余不但可能导致代码可读性的降低(多次重复编写一大段代码),还可能降低代码运行的效率(代码容量的增加导致的程序装载效率以及多次进行结果必然相同的表达式运算)。在软件工程的哲学中有一个广为人知的原则,叫做 DRY 原则,全称是 Do not Repeat Yourself,是避免冗余的基本原则,意思是不要让相同的代码出现大于一次。例如:

  1. a = 0
  2. b = 32
  3. for i in 0..100
  4.   a += i
  5. end
  6. for i in 5..323
  7.   b += i
  8. end
  9. p a + b
复制代码
我们这里有两个整数 a 和 b,分别初始为 0 和 32,我们想让它们的值递增上一系列连续的整数,于是写了两个框架基本上一样的循环。其中第二个循环就是冗余代码,我们完全可以编写一个函数(子例程)来完成这一个运算:
  1. def fn(a, b)
  2.   ret = 0
  3.   for i in a ..b
  4.     ret += i
  5.   end
  6.   return ret
  7. end

  8. a = 0
  9. b = 32
  10. a += fn(0, 100)
  11. b += fn(5, 323)
  12. p a + b
复制代码
这是提高了代码可读性的冗余消除。另一种情况:
  1. def fn(a, b)
  2.   $global = a*b
  3.   return a*b
  4. end
复制代码
这里,return 语句则是一句冗余代码,因为它在第一次计算 a*b 且结果保存在了 $global 后第二次计算了 a*b,而这是不必要的,因为 $global 这个变量是永远可见的,可以直接引用它并返回:

  1. def fn(a, b)
  2.   $global = a*b
  3.   return $global
  4. end
复制代码
然而这还属于无伤大雅的冗余,毕竟如今的 CPU 条件下,可以在极其高效的对数时间内完成乘法运算;糟糕的是出现需要花费时间执行的代码出现了冗余:
  1. arr = [1, 3, 52, -2, 0, -234, 33, 6, 76, 44, 3, -2, 5]
  2. res = 0
  3. res += 6 if arr.include?(6)
  4. res += arr.sort[2]
  5. if arr.include?(6)
  6.   res += arr.sort[3] << 3
  7.   p "#{res}foo"
  8. end
  9. p "#{res}bar"
复制代码
这里,arr.include? 和 arr.sort 都出现了两次,而由于期间 arr 没有改变,故这两者的第二次出现都是冗余代码;恰好这两者都是耗时间的操作——include? 需要线性时间内完成,而 sort 需要线性对数时间内完成。我们将冗余消除后,理论上运行效率会提升将近一倍:

  1. arr = [1, 3, 52, -2, 0, -234, 33, 6, 76, 44, 3, -2, 5]
  2. res = 0
  3. has6 = arr.include?(6)
  4. sorted_arr = arr.sort
  5. res += 6 if has6
  6. res += sorted_arr[2]
  7. if has6
  8.   res += sorted_arr[3] << 3
  9.   p "#{res}foo"
  10. end
  11. p "#{res}bar"
复制代码
然而你也不能只留意在源脚本中实际出现了多次的代码冗余,有时在某些特殊控制结构里,比如循环,即时表达式在字面上仅出现了一次,实则也可能是一种冗余:
  1. arr = [1, 3, 52, -2, 0, -234, 33, 6, 76, 44, 3, -2, 5]
  2. for i in 0..100
  3.   sorted_arr = arr.sort
  4.   p sorted_arr[rand(sorted_arr.length)]
  5. end
复制代码
这里,arr.sort 会被循环执行,但实际上进行排序的数组没有改变,每次排序的结果都是相同的,所以我们可以把这一行拿到循环外面去,避免了冗余:
  1. sorted_arr = arr.sort
  2. for i in 0..100
  3.   p sorted_arr[rand(sorted_arr.length)]
  4. end
复制代码
假设数组长度是 n,那理论上这里的冗余避免后效率是避免前的将近 100 倍。
DRY 原则也不是绝对要遵守的,要看情况而定——有时出现的冗余,比如多次通过 [] 数组下标访问数组元素,影响并不大,因为它们并不耗费多少时间,为了它们去分配一个临时变量来保存可能并不值得。在编译性语言以及有即时编译机制的解释性语言中,聪明的编译器和解释器会自动进行各种优化,如公共子表达式消除、死代码消除、常数合并,能杜绝大部分冗余,但 RM 所使用的 Ruby 1.8 MRI 解释器直接解释源代码,没有任何优化,所以是需要用户来考虑效率的

点评

inline 还是交给编译器处理吧 o.o 用得不好反而会降低效率  发表于 2010-9-3 22:00
那瞬间inline关键字在我心中怒吼……  发表于 2010-9-3 18:13
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
10
发表于 2010-9-2 10:06:13 | 只看该作者
2010-09-02 Proc.new 和 lambda
Proc 是 procedure 的简称,意味着一个过程,或者例程。我们基本上可以把 Ruby 的 Proc 对象看作是 Ruby 的匿名函数,但在 Ruby 1.8 中,通过不同方法获取的 Proc 对象有微妙的区别:
  1. def foo
  2.   local = 'This is a local variable'
  3.   $proc = Proc.new { return }
  4.   $proc.call # OK
  5.   p '这里永远不会执行'
  6. end

  7. foo
  8. $proc.call # error
复制代码
在 foo 方法内部,$proc 执行后,直接结束了函数的运行,而在方法外部调用 $proc 则会产生非局部跳转的异常,这里的意思是告诉你不能在顶层 return。从这个现象可以得出结论:Proc.new 会绑定创建时的上下文,而在这个 Proc 对象内 return 则是与该上下文绑定的。比如,上面的代码中,$proc 创建时的上下文是 foo 方法的局部上下文,在方法内部调用 $proc 时 foo 的局部上下文还存在(方法还没有返回),所以没有问题;在方法外部调用 $proc 时 foo 的局部上下文已不复存在(方法已经返回),所以发生了异常
我们再来看看闭包的定义:
在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。

然而 Proc.new 产生的 Proc 对象并没有真正的自由,它与创建时的上下文绑定在了一起,并不是一个独立的匿名函数个体(因为不能自由地 return,且成功 return 后会让外部的函数返回),所以它并不算是真正意义上的闭包
可喜的是,刁钻古怪的 Ruby 还是用一种隐晦的方式提供给了我们真实的闭包。把上面的代码中的 Proc.new 替换为 lambda 后,就能发现没有错误了。lambda 是 Kernel 里的方法,这个名称来源是 λ-calculus 中的 λ 符号,意味着一种匿名函数演算法,由 Scheme 语言最早支持,后来被各种语言继承。lambda 产生的 Proc 对象,其内部 return 是从当前的 Proc 对象,即当前的闭包返回,所以 lambda 产生的 Proc 对象才是 Ruby 真正的闭包
这里还有最后一个问题,就是 Ruby 1.8 对 proc 和 lambda 的定义产生了混淆。proc 也是 Kernel 里的一个方法,其文档中表示 Kernel#proc 等价于 Proc.new,但当我们实际把上面代码中的 Proc.new 替换为 proc 时,会发现没有异常。实际上在 Ruby 1.8 中,Kernel#proc 是等价于 Kernel#lambda 的,也就是说 Kernel#proc 也是真实的闭包。然而从命名上来看,proc 和 Proc.new 不同而合 lambda 相同,是一个很明显的设计失误,所以在 1.9 中,Ruby 巧妙地让 Proc.new 等价于了 Kernel#proc

点评

这个地方说的有歧义,应该换一下顺序,proc 等价于了 Proc.new,也就是并非真正的闭包  发表于 2010-9-26 21:54
【所以在 1.9 中,Ruby 巧妙地让 Proc.new 等价于了 Kernel#proc】的意思是说,Proc.new变成真正的闭包,而不需要lambda了?  发表于 2010-9-26 17:03
回复 支持 反对

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
9
发表于 2010-9-1 08:49:17 | 只看该作者
本帖最后由 小幽的马甲 于 2010-9-1 08:50 编辑

2010-9-1

垃圾回收(Garbage Collection)

GC是个很有意思的东西。不管是用C的malloc和free还是Pascal的new和dispose管理内存都需要有一个释放的过程,有的时候会很麻烦,GC就是把这个过程智能化了,可以把不用的对象(垃圾)自动释放掉。
RM里的GC模块只有三个方法:GC.enable(打开GC)、GC.disable(关闭GC)、GC.start(初始化GC),很好理解。
为了测试GC的效果,我们可以在事件里调用
  1. a = Window_Help.new
  2. a = 1
复制代码
执行后可以看到,地图上仍会留一个窗口,但是约一分钟后就会自动消失。
如果后面加句GC.start则会立刻消失。
当然,平时写脚本是绝对不要依赖GC,该释放的对象还是要释放。
默认脚本中只有在Cache.clear里用到了GC,因为那时候缓存的哈希表被清空,但对象并没有被释放,所以需要调用GC。

点评

http://bbs.66rpg.com/thread-214626-1-2.html @紫苏君……  发表于 2012-1-12 14:45
我昨天NC了,“左值右值都是常量形式”无视这句  发表于 2010-9-1 23:05
1+1 你就这么写的(左值右值都是常量形式)?1.9 的 YARV 虚拟机可以做循环优化,让 1+1 在循环中只运算一次结果,因为运算元恒定;而 1.8 则毫无优化  发表于 2010-9-1 12:19
我没测1.9.2的GC效率咋样,不过测了10**7次1+1,192效率比RM高一倍  发表于 2010-9-1 11:20
>zh 释放是指调用dispose方法囧  发表于 2010-9-1 10:21
From mortal hope immortal power springs.
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1045
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

8
 楼主| 发表于 2010-8-31 00:02:57 | 只看该作者

2010-08-31

本帖最后由 DeathKing 于 2010-8-31 00:37 编辑

三元表达式、三元运算符(Ternary Operator

  平常接触的if控制结构都是这样的:
  1. if condition
  2.   exp1
  3. else
  4.   exp2
  5. end
复制代码
不过当exp只有一句的时候,这样看起来会十分的占地方,所以就有了下面这种简写为一排的方式:
  1. if condition then exp1 else exp2 end
复制代码
不过这样看起来也有很大一堆,还有没有更简单、优雅的写法呢?当然是有的,Ruby继承了C的三元运算符(Ternary Operator),上面的表达式会被替换成这样:
  1. condition ? exp1 : exp2
复制代码
实质上,首先会计算condition的值,为真的话就执行exp1,否则就就只exp2。不过要注意的是,三元运算符的优先级比=(赋值运算符)高,所以下面的做法是完全可行的:
  1. foo = true ? 1 : 0
  2. p foo #=> 1
复制代码
如果说你是Visual Basic程序员,你会发现,三元运算符就和IIf函数类似。

点评

vb 的 iif 函数可不是惰性求值。  发表于 2011-8-21 00:35
三目运算符是个好东西~恩~ 而且特别喜欢ruby可以把if或者unless写在表达式后面的写法  发表于 2010-9-2 13:59
= =这种写法还不如同行if..else简洁  发表于 2010-8-31 13:55
还有个写法:condition and (expr1 or true) or expr2,纯粹是玩弄逻辑算术及其短路特性 =v=  发表于 2010-8-31 00:15

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

Lv2.观梦者 (管理员)

八云紫的式神

梦石
0
星屑
549
在线时间
1243 小时
注册时间
2008-1-1
帖子
4282

烫烫烫

7
发表于 2010-8-30 08:18:07 | 只看该作者

2010-8-30

重名陷阱

由于Ruby在语法上很人性化很自由,这也就带来了一些问题

例如
1.在方法调用中省略括号所引起的误会  注:标引用的部分引自Ruby手册
因为表示Range对象(或范围表达式)的.., ...的结合度较低(请参考操作符表达式),所以会引发下列错误
1..3.to_a
=> -:1: bad value for range (ArgumentError)
上面的代码会被解释成下面这个样子。
1..(3.to_a)
下面的代码不会得到预期的结果
p (1..3).to_a
因为它被解释成下面的代码。
(p (1..3)).to_a
p (true && true)    #=> true
p (true and true)   #=> parse error
p ((true and true)) #=> true
因为true and false被看作是语句,所以必须使用括号将其变为表达式的等价形式。同时,将它传给p的参数时还需要再加上一层括号才行。
p {1=>2}    #=> parse error (大括号被当作块)
p ({1=>2})  #=> {1=>2}
p (1=>2)    #=> {1=>2} (参数被当作哈希表)
p (1=>2, 3) #=> parse error    (只能把省略大括号的哈希表放在参数列表的最后)
p (0,1=>2)  #=> 0
                1=>2

2.运算符和方法的重名
a=1;
b = a+2;   # a 和 2 的和
b = a +2;  # 被解释成 a(+2)
b = a + 2; # a 和 2 的和

a = b = c = true
a?b:c       # 被解释成 a?(b(:c))
a ? b : c   # 条件操作符

3.变量和方法的重名
以小写字母开头的方法,可能与变量重名
  1. def a
  2.   1
  3. end
  4. p a #=>1
  5. a = 2
  6. p a #=> 2
  7. p a() #=> 1
复制代码
如果没有a这个变量,那么只p a就可以输出1
但是大写字母则不同,无论有没有同名常量,都必须加()
  1. def A
  2.   1
  3. end
  4. p A #=>出错
  5. A = 2
  6. p A #=>2
  7. p A() #=>1
复制代码
带等号方法
  1. def a=(val)
  2.   @a = val
  3. end
  4. a = 1
  5. p @a #=> nil
  6. self.a = 1
  7. p @a #=> 1
复制代码

点评

个人觉得空格不是一种好的习惯..因为可以代替空格的字符实在是太多了..  发表于 2010-12-28 09:35
这不是手册上的吗~~~话说第2点“运算符和方法的重名”在RM里试过了~~~欲知后事如何,自己试~~~  发表于 2010-9-30 11:36
受教了~原来还有这种事啊……看来好的编程习惯很重要啊~  发表于 2010-9-2 14:02
moy
空格果然是好东西.....  发表于 2010-8-31 00:30
看来要工整的写才行。。  发表于 2010-8-30 14:35
rm for linux(wine)制作中,期待夏娜SAMA能实现到webrm上
回复 支持 反对

使用道具 举报

Lv3.寻梦者

孤独守望

梦石
0
星屑
3121
在线时间
1534 小时
注册时间
2006-10-16
帖子
4321

开拓者贵宾

6
发表于 2010-8-28 18:26:52 | 只看该作者

2010-8-29

本帖最后由 IamI 于 2010-8-29 12:59 编辑

Class、Module两个类是抽象的抽象。在Class中定义的实例方法是Class类的对象的方法,也就是普通的类的类方法。比如说:
  1. class Class
  2.   def hi
  3.     p "HI!"
  4.   end
  5. end

  6. class A
  7.   hi
  8. end
  9. A.new.hi
复制代码
不言自明。

Class和Moudle的类方法只能被显式的调用,诸如Class.new

另外,事实上,假设A是一个类,当你调用A.new方法的时候,操作如下所示:
A.new调用A.allocate => 生成实例
调用实例的initialize方法 => 根据伪多态完成初始化操作。

Object是一切的起源。它是超脱一切的存在(囧)。Object的include-in Kernel(你没看错,它是一个Mix-in)可以在任何位置被调用。也许你会问。既然Kernel是一个嵌入模块,那么为什么在没有类没有实例的方法也可以调用?因为直接p self可以(VX)看到顶级被调——Main :Object。是的,你逃不出Object的掌控。

如果你要给所有类定义一个方法,想在Class类eval?错了,instance_eval。具体请参考一开始的那段话。

OK,给下面两楼两个话题。Binding、$SAFE

点评

多么熟悉的声音,陪我多少年风和雨,从来不需要想起,永远也不会忘记——没 Object 哪有 Module,没 Module 哪有 Class,没 Class 哪有人类,没人类哪有你……   发表于 2010-8-29 12:06
其实我一直觉得Class是个牛逼的自描述:Class.class #=> Class O_O  发表于 2010-8-29 08:40
另外在万恶的XP里,顶层p self是nil,把我囧个半死。。  发表于 2010-8-29 08:00
DK那个是28号的了。。。你这个当29号的吧,标题给你编辑了  发表于 2010-8-29 07:58
菩提本非树,明镜本非台。回头自望路漫漫。不求姻缘,但求再见。
本来无一物,何处惹尘埃。风打浪吹雨不来。荒庭遍野,扶摇难接。
不知道多久更新一次的博客
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1045
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

5
 楼主| 发表于 2010-8-27 08:43:26 | 只看该作者

有关方法名的一些俗成约定

本帖最后由 DeathKing 于 2010-8-29 07:19 编辑

2010-08-28

昨天进行过一次讨论:http://rpg.blue/thread-154899-1-1.html
既然抢到了今天的帖子,那么就借花献佛。

Ruby中的方法名有一定的俗成的约定,下面列出了这些约定,不过,这不是强制性必须遵守的!

以 = 号结尾的方法通常是setter,会为同名实变量设定值;
以 ? 号结尾的方法返回的是一个所谓的布林值,也就是true或者false;
以 ! 号结尾的方法表示该方法具有破坏性,所以要小心操作。

一些例子:
  • 由元编程方法 attr_writer :methodattr_accessor :method 建立的 method= 方法就会为 @method 实变量赋值;
  • Object 类提供的 is_a? 方法返回 true 或者false ,来判断对象是否是一个类的实例,如: 1.is_a? Fixnum #=> true
  • String 类提供的gsub! 方法比较常见(Window_Message 大多用这个方法处理),它就具有破坏性,直接在源对象上操作;

关于破坏性与非破坏性的比较:

  1. ary = [1,3,5,7,9,2,4,6,8,10]

  2. ary.sort #=> [1,2,3,4,5,6,7,8,9,10]
  3. p ary    #=> [1,3,5,7,9,2,4,6,8,10]

  4. ary.sort! #=> [1,2,3,4,5,6,7,8,9,10]
  5. p ary     #=> [1,2,3,4,5,6,7,8,9,10]
复制代码

点评

布林?布尔?  发表于 2010-8-30 14:38
带 `=' 的函数也可以叫 modifier、mutator,带 `?' 的则是 predicate  发表于 2010-8-29 00:40
我错了,原来我没看清楚规则……昨天看成一人每天限回复1贴了  发表于 2010-8-27 09:23
DK你来晚了  发表于 2010-8-27 08:53

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

Lv2.观梦者 (管理员)

八云紫的式神

梦石
0
星屑
549
在线时间
1243 小时
注册时间
2008-1-1
帖子
4282

烫烫烫

4
发表于 2010-8-27 08:39:48 | 只看该作者

2010-08-27 简略写法

p不是关键字,但是可以执行p 1正常输出1而不出错,为什么?
Ruby里调用方法时,如果不会产生歧义,则可以省略括号,使代码变得整洁美观
比如要输出一个跟RM里的用语【等级】同名的文件,可以简写成这样
  1. print IO.read Vocab.level
复制代码
这比完整写法
  1. print(IO.read(Vocab.level()))
复制代码
好看的多
但是一定要注意使用时的原则是不引起歧义,例如
  1. open File.expand_path "test.txt" , "w"
复制代码
就会出错,原因是参数"w"可能是expand_path的参数也可以是open的参数
所以必须加一层括号
  1. open File.expand_path("test.txt") , "w"
复制代码
Ruby中类似的简写除了括号之外,还有其他的,例如Hash
  1. p 1 => 2
复制代码
乍一看似乎是会Syntax,但是这一句是能执行的,输出{1 => 2}
这一特性在ruby的应用(窗口编程/网页)中使用得十分广泛

点评

只推荐用于单参数  发表于 2010-8-27 10:55
这样可能会一定程度降低可读性,使用时确保自己熟悉每个方法的参数  发表于 2010-8-27 09:08
点了回复的时候没看到嘛 >_< 结果就撞上了,不过今天入账2枚,收获颇丰啊。  发表于 2010-8-27 08:57
rm for linux(wine)制作中,期待夏娜SAMA能实现到webrm上
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
3
发表于 2010-8-26 10:55:10 | 只看该作者
有人会问:Ruby 没有析构方法?乍一看似乎这个真没有,其实这个可以有——
define_finalizer  ObjectSpace.define_finalizer( anObject, aProc=proc() )  

Adds aProc as a finalizer, to be called when anObject is about to be destroyed.  

ObjectSpace.define_finalizer 可以为某个对象添加一个类似 C++ 析构函数的最终化处理器,如果在 initialize (类似构造函数)中调用这个方法,就能为每个实例添加一个固定的析构方法
例:

  1. class MySprite < Sprite
  2.     def initialize(viewport = nil)
  3.         super(viewport)
  4.         ObjectSpace.define_finalizer(self, proc { self. dispose })
  5.     end
  6. end
复制代码
这样一来,当 MySprite 对象被回收时,精灵资源会自动释放

点评

moy
上的就是信息技术专业...准备朝编程方向发展,主要是蛮感兴趣的说~不过糟糕的是我数学不太好于是在起跑线上就被拉后腿了T_T  发表于 2010-8-28 01:20
@moy:呵呵,慢慢来~其实我觉得如果不想主走成程序的路没必要钻研太深,还是找朋友合作比较好,就像我不可能从头学美术一样……  发表于 2010-8-27 09:16
补充:Proc 还不是 Ruby 真正的闭包,lambda 才是,详见:[url]http://bbs.66rpg.com/forum.php?mod=viewthread&tid=153979[/url]  发表于 2010-8-27 09:15
moy
不管是内容还是点评一概都雾水了@_@,我还有很长的路要走啊.....好多概念都空白呢  发表于 2010-8-27 07:25
没错,实际上就是闭包的概念  发表于 2010-8-27 01:19
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-27 02:32

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表