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

Project1

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

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

  [复制链接]

Lv3.寻梦者

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

贵宾

84
 楼主| 发表于 2011-2-10 01:42:44 | 只看该作者
本帖最后由 DeathKing 于 2011-2-10 10:50 编辑

New Ruby 1.9 Features, Tips & Tricks: http://www.igvita.com/2011/02/03 ... atures-tips-tricks/




补一些重要的翻译

* Ruby 1.9.X Oniguruma作为新的正则式引擎。(关于Oniguruma引擎的特性,请看之前紫苏的相关介绍);
* Ruby 1.9.X 允许带有默认值的参数放在前面了。
  1. def f(a=1, b); p [a,b]; end;
  2. p f(2) # => [1, 2]
复制代码
* Ruby 1.9.X 默认使用 Object#inspect 来代替to_s;
  1. puts({a:1, b:[2,3]}.to_s) # => {:a=>1, :b=>[2, 3]}
复制代码
* Ruby 1.9.X 加入了一个 Hash#assoc 方法,返回 [key, hsh[key]]
  1. p({a: 1, b: 2}.assoc(:b)) # => [:b, 2]
复制代码
* Ruby 1.9.X 允许你把可变参数放在参数列表的任何位置;
  1. def a(a,*b,c); p [a,b,c]; end
  2. p a(1,2,3,4) # => [1, [2, 3], 4]
复制代码
* Ruby 1.9.X 能对符号使用正则式了;
  1. p :ruby_symbol.match(/symbol/) # => 5
复制代码
* Ruby 1.9.X 提供了一种新的建立Hash的方法,这种方法更加紧凑;
  1. p({a:1, b:2}) # => {:a=>1, :b=>2}
复制代码
* Ruby 1.9.X 提供了一种建立 stabby proc 的方法(个人认为类似于lambda表达式?);
  1. f = -> a,b { p [a,b] }
  2. p f.call(1,2) # => [1, 2]
复制代码
* Ruby 1.9.X 的 Hash 已经有序了;(可以参见之前的讨论)
  1. p({a:1, b:2}) # => {:a=>1, :b=>2}
复制代码
* Ruby 1.9.X 提供了4种调用Proc的方法;
  1. f =->n {[:hello, n]}
  2. p f[:ruby]       # => [:hello, :ruby]
  3. p f.call(:ruby)  # => [:hello, :ruby]
  4. p f.(:ruby)      # => [:hello, :ruby]
  5. p f === :ruby    # => [:hello, :ruby]
复制代码
* Ruby 1.9.X 不再支持 String#each 方法了,请使用chars,bytes,lines,each_char等(个人猜测是因为each容易引起歧义?);
* Ruby 1.9.X 添加了 Enumerable#sample(n) 方法,随机抽出 n 个元素(个人认为是模拟抽样);
  1. p [1,2,3,4].sample(2)  # => [2, 3]
复制代码
* Ruby 1.9.X 添加了Kernel#define_singleton_method 函数,以后定义单例可以这样做:
  1. c = 'cat'; c.define_singleton_method(:hi) { p 'hi' };
  2. p c.hi  # => "hi"
复制代码
* Ruby 1.9.X 提供了能创建生命周期只在块中的临时变量;
  1. v = 'ruby'; [1,9].map {|val; v| v = val }
  2. p v # => "ruby"
复制代码
* Ruby 1.9.X 允许块使用块作为参数了;
  1. b = -> v, &blk { p [v, blk.call] }
  2. p b.call(:a) { :b } # => [:a, :b]
复制代码
* Ruby 1.9.X 将线程映射到 OS 的线程上;(订正请求:"Ruby 1.9 threads are now mapped (1:1) to OS threads! ex: gdb -p [ruby PID], info threads - yes, there is still a GIL.")
* Ruby 1.9.X 加入了新的垃圾回收方法,GC.count和GC::Profiler;
  1. GC::Profiler.enable; GC.start; puts GC::Profiler.result
复制代码
* Ruby 1.9.X 允许你内观 Ruby 虚拟机 YARV 编译好的字节码;
  1. puts RubyVM::InstructionSequence.compile('a = 1; p 1 + a').disassemble
复制代码

点评

@zh 我之前在先行者说过全局解释器锁(GIL)的原理,在 GIL 的淫威下即便是内核线程之间也无法真正的并发。我改天在这里也发一贴吧。  发表于 2011-3-23 14:42
Thread.new{loop{1}} Thread.new{loop{1}}.join 这个占不满两个CPU核心而只能占满一个,如果是内核线程的话应该能满两个才对,求解释 版本是192p0  发表于 2011-3-1 17:24
终于有OS内核线程了  发表于 2011-2-20 08:14
这里 stabby proc 在本主题中我的一篇回复中提到过,就是 lambda 的语法糖。  发表于 2011-2-10 12:01
yes, there is still a GIL. => 没错,GIL (全局解释器锁)这鬼东西仍然健在。这个我好像之前在先行者发过相关的介绍……  发表于 2011-2-10 11:58

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

使用道具 举报

Lv3.寻梦者

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

贵宾

83
 楼主| 发表于 2011-2-9 16:05:58 | 只看该作者
本帖最后由 DeathKing 于 2011-2-9 16:09 编辑

这是去年的旧事了(2010-06-18)

Matz 博客透露红宝石2.0新功能
http://chinaonrails.com/topic/view/4111/1.html
http://www.rubyist.net/~matz/20100618.html
  1. def foo(a, b: 42, **keys)
  2.    p [a,b,keys]
  3. end

  4. foo(1)             # => [1,42,{}]
  5. foo(2, b: 5)       # => [2,5,{}]
  6. foo(3, b: 4, c: 6) # => [3,4,{:c=>6}]
复制代码
处理可变参数列表就方便了。

点评

具体如何还得看 RubySpec 最后如何定了……Matz 在 RubyConf 上明确说了他会撒手不管 2.0,转而去搞 Rite  发表于 2011-2-10 01:11
呃,我看到了...不用回答了..貌似比我想的还要优化点..  发表于 2011-2-9 22:08
看题应该是 这样.. foo(1,,c:6)这样问  发表于 2011-2-9 22:06
foo(,,c:6)可以这样吗?  发表于 2011-2-9 22:04

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

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
82
发表于 2011-2-8 05:47:52 | 只看该作者
本帖最后由 苏小脉 于 2011-4-2 19:40 编辑

要注意区分传统的捕获组引用和 79、80 楼所提到的引用方式的区别。79、80 楼使用的 \g<name> 语法,是将捕获组当作是一个子程序(subroutine)在用,就好比定义了一个函数,每次去调用它都会进行新的匹配。

传统的引用是这样的:
  1. str = 'a1:13:9f:dd:32:72'
  2. regex = /(\h)\1/
  3. p str[regex] # => "dd"
复制代码
`(\h)' 是一个捕获组,而后面跟着一个后向引用,这不会再次进行 `\h' 的匹配,而是拿捕获组匹配后的结果来进行匹配。所以,这个表达式实际上匹配的是两个相同的十六进制数位,那么在 str 中,只有 `dd' 是匹配的。

由于 1.9 支持命名捕获组,那么想要依然使用以上方式的后向引用自然也需要扩展语法。

  1. str = 'a1:13:9f:dd:32:72'
  2. regex = /(?<hex>\h)\k<hex>/
  3. p str[regex] # => "dd"
复制代码
而如果把 \k 替换为 \g,那就和 79、80 楼一样,重新对“子程序”进行了求值,所以可以匹配任意两个十六进制数位。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
81
发表于 2011-2-7 06:17:43 | 只看该作者
80 楼提到了递归性质的正则表达式。Oniguruma 的递归仍然是通过命名捕获组完成的,这里就做一个演示。

我们有一段很简单的代码字符串:
  1. str = <<STRING_ENDS_HERE
  2. void main() {
  3.     int i;
  4.     if (1) {
  5.         int a;
  6.         if (10) {
  7.             int var;
  8.             if (1) {
  9.                 int i;
  10.             }
  11.         }
  12.         int b;
  13.     }
  14. }
  15. STRING_ENDS_HERE
复制代码
而我们希望通过正则表达式来取出语法正确的 if 语句代码块。
  1. regex = /

  2. (?<if>
  3.     if\s*\(\d*?\)\s*{\s*
  4.         (?:int\s*[a-zA-Z]\w*?;\s*|\g<if>)*
  5.     \s*}\s*
  6. )

  7. /xm
复制代码
这里我们限制了一个语法正确的 if 语句为:
if,跟着可能的空白,跟着 (,跟着一个数字,跟着 ),跟着 {,跟着可能的空白,跟着另一个语法正确的 if 语句,或者跟着一个 int 变量的声明,最后跟着 } 和可能的空白。那么我们:

  1. p str[regex]
复制代码
就能捕获到最外围的 if 语句。当 if 后面少了 ( 或 ),或是少了 { 或 },抑或是 int 变量声明少了 ;,就是一个语法错误,那么就不匹配我们上面所写的 regex。比如,我们故意去掉 int var 后面的分号:

  1. str = <<STRING_ENDS_HERE
  2. void main() {
  3.     int i;
  4.     if (1) {
  5.         int a;
  6.         if (10) {
  7.             int var
  8.             if (1) {
  9.                 int i;
  10.             }
  11.         }
  12.         int b;
  13.     }
  14. }
  15. STRING_ENDS_HERE
复制代码
p str[regex] 则是:
"if (1) {\n                int i;\n            }\n        "

因为外围的 if 内部有语法错误,所以只有最里层的 if 被匹配了。

这只是一个很简陋的语法匹配,但演示了如何使用递归匹配。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
80
发表于 2011-2-6 13:48:59 | 只看该作者
Ruby 1.9 使用了一个效率更高、功能更强大的正则表达式引擎——Oniguruma(鬼車)。相比于 Ruby 1.8 的正则表达式引擎来说,Oniguruma 所能描述的再也不仅仅是正则语言了。这其中的一个重要因素是由于递归表达式的出现——正则语言的一大特点就是没有递归。和大多数现代化的引擎一样,Oniguruma 甚至能用来描述上下文无关语言这样的形式语言。可是,“正则表达式”这个术语仍然被各种语言持续使用了下来。可能人们对正则表达式太熟悉了,熟悉到会觉得其名称改为“形式表达式”很别扭。

本帖主要介绍一个新功能:命名捕获组

对于能熟练使用正则表达式的朋友来说,捕获组并不陌生。未经转义的圆括号中的表达式就是一个捕获组,我们之后可以在表达式中引用这个捕获组。传统的引用方式是通过所谓的后向引用,即 \n 的形式,来引用在表达式中从左到右第 n 个出现的捕获组。

这种方式有很多弊端。首先,用户必须维护 1, 2, ..., n 这些数字。一旦发生两个捕获组换位的情况,就要把所有的它们的后向引用都改掉,这对于较长的表达式来说无疑是力气活。如果我们能给捕获组命名,那么即便它的位置变了,名字却不会变,所以无须修改其引用处。

其次,对于代码阅读者来说(把整个表达式背下来的除外),一个数字只不过是一个密码,它本身并不能让读者直接回想起任何已知事物,读者只能从头开始阅读表达式,并按出现顺序找到对应的捕获组,这属于一个简单的破译过程。如果我们给捕获组命名,那么就可以通过一两个单词来简短地描述该捕获组所接受的语言。比如:将一个捕获组命名为“alphanum”,那么读者大概就能猜到这个捕获组匹配的是“alphanumeric”的值,也就是字母或数字。

Oniguruma 命名捕获组是通过 (?<name>regex) 的语法来完成的。name 是捕获组的名称,regex 是捕获组内部的正则表达式。

  1. #coding: GBK

  2. regex = /(?<hex>[0-9a-fA-F])\+\g<hex>/
  3. str = '我们需要取出4+f这个子串!'
  4. p str[regex] # "4+f"
复制代码
如果我们在命名捕获组时配合正则表达式的“忽略空白符”选项(字面值后添加 `x' 后缀),以及在捕获组子表达式后添加 {0} 表示匹配 0 次,就可以大大地提高表达式的可读性。给一个比较复杂的例子,是我之前写的一个匹配电子邮件地址的雏形:
  1. #coding: GBK

  2. # local@domain

  3. $pattern = %r<

  4. # Define subpatterns.
  5. (?<local>       \g<local_t>|\g<quoted>              ) {0}
  6. (?<local_t>     \g<local_a>+(?:\.\g<local_a>+)*     ) {0}
  7. (?<local_a>     \g<alphanum>|[!\#$\%&'*/=?^_`{|}~-] ) {0}
  8. (?<alphanum>    [a-zA-Z0-9]                         ) {0}
  9. (?<quoted>      ".*"                                ) {0}
  10. (?<domain>      \g<hostname>|\[\g<ip_addr>\]        ) {0}
  11. (?<hostname>    \g<label>(?:\.\g<label>)*           ) {0}
  12. (?<label>       \g<alphanum>+(?:-+\g<alphanum>+)*   ) {0}
  13. (?<ip_addr>     \g<zero_255>(?:\.\g<zero_255>){3}   ) {0}
  14. (?<zero_255>    \d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]   ) {0}

  15. # The root pattern is ...
  16. \g<local>@\g<domain>

  17. >x
复制代码
这里,由于使用的是 %r 来构建正则表达式,所以其内部可以直接写普通的注释。每个子表达式后面跟上 {0},表示这里仅仅是定义并命名一个捕获组,并不参与实际匹配。再加上最后的 `x' 后缀,表达式中的空白都会被忽略,所以可以对表达式进行缩进。这个例子就大量使用了命名捕获组,将匹配不同字符串片段的表达式分划到了不同的子表达式。这在便于维护的同时也提高了可读性,和代码模块化是一个道理。

http://szsu.wordpress.com/2010/11/13/regex_email_addr/
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv2.观梦者

傻♂逼

梦石
0
星屑
369
在线时间
1605 小时
注册时间
2007-3-13
帖子
6562

烫烫烫开拓者

79
发表于 2011-1-27 00:13:07 | 只看该作者
哎呀,蛋疼什么的最有爱了
回复 支持 反对

使用道具 举报

Lv3.寻梦者

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

贵宾

78
 楼主| 发表于 2011-1-24 20:30:04 | 只看该作者
偷个小懒:
Ruby排序算法收集:http://www.javaeye.com/topic/746562

不过个人觉得,个个类的sort方法不然各具特色,也是最方便最好用的了。

点评

其实用 Ruby 写排序的意义只停留在学术研究和演示层面上,实用性几乎为零 o.o  发表于 2011-1-25 01:26

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

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
77
发表于 2011-1-22 14:33:33 | 只看该作者
(承接 76 楼)

instance_eval 和 class_eval 的区别,也是在于对 default definee 的处理上。由于 class_eval 是 Module 类的实例方法,所以下面进行测试使用的接收者是一个兼容 Module 类型的实例(其运行时类型是 Class 类型),否则 class_eval 这个方法压根儿没法用。另:module_eval 只是 class_eval 的一个别名,但如果按照 Ruby 编程的习俗,我们通常会对一个可能是 Module 类型的对象则使用 module_eval,而其余场合则使用 class_eval。

其实你需要记住的就一句话:在 instance_eval 的块内部,self 会指向 instance_eval 的接收者,而 default definee 会成为接收者的 eigenclass(关于 eigenclass 可以参考 73 楼);在 class_eval 的块内部,self 和 default definee 都会成为 class_eval 的接收者。
  1. class Klass
  2. end

  3. Klass.instance_eval do
  4.     def class_method
  5.         p :class_method
  6.     end
  7.     def self.another_class_method
  8.         p :another_class_method
  9.     end
  10. end

  11. Klass.class_eval do
  12.     def instance_method
  13.         p :instance_method
  14.     end
  15.     def self.yet_another_class_method
  16.         p :yet_another_class_method
  17.     end
  18. end

  19. k = Klass.new
  20. k.instance_method               # => :instance_method
  21. Klass.class_method              # => :class_method
  22. Klass.another_class_method      # => :another_class_method
  23. Klass.yet_another_class_method  # => :yet_another_class_method
复制代码
我们一步一步地来看。

首先,我们在 instance_eval 的块内部定义了一个普通方法 class_method,这是实例方法的定义方式。什么?你问我为什么把它命名为“类方法”(class_method)?别忘了之前的那句加粗的话。在 instance_eval 的块内部,default definee 会成为 instance_eval 的接收者的 eigenclass。此处,instance_eval 的接收者是 Klass,所以我们定义的 class_method 方法实际上就成为了 Klass 的 eigenclass 的实例方法,这用以前的术语来说,就是定义了 Klass 这个对象(Klass 是 Class 类型)的单例方法(singleton method)。而我们知道,Class 对象的单例方法,实际上就是传统意义上的“类方法”,也就类似于 Java、C# 中的类静态方法。所以此处的 class_method 就成为了 Klass 类的类方法,在最后的输出语句中,可以直接通过 Klass 这个 Class 对象来调用 class_method 方法,而不需要 Klass 的实例。

之后我们又定义了一个 another_class_method,这次是用定义单例方法的方式定义的,因为在方法名前多了一个接收者 self。之前说了 instance_eval 的块内部的 self 会指向 instance_eval 的接收者,也就是这里的 Klass,所以 self 实际上就是 Klass 这个 Class 对象。我们对 Klass 这个对象定义单例方法,那就相当于定义了 Klass 的 eigenclass 的实例方法,所以和上面定义 class_method 的上下文没有区别,都是 Klass 的 eigenclass,故而他们都是 Klass 的类方法。

接着我们进入了 class_eval,然后定义了一个 instance_method。再次回顾之前被加粗的那句话,我们就知道,class_eval 的块的内部的 default definee 会成为 class_eval 的接收者,在这里就是 Klass 本身,所以我们定义的 instance_method 就成为了 Klass 的实例方法。在最后的输出语句中,可以看到通过 Klass 的实例 k 调用 instance_method。

最后我们又通过单例方法定义的形式定义了一个 yet_another_class_method 方法。class_eval 的块内部的 self 仍然是指向 class_eval 的接收者,也就还是 Klass 本身,所以 self 仍然是指向 Klass。如此一来,这个方法定义又成了给 Klass 这个对象定义单例方法,所以和 class_method、another_class_method 一样都是 Klass 的类方法,故而命名为 yet_another_class_method。

所以,千万不要被 instance_eval 和 class_eval 的名字迷惑。在 Module#instance_eval 中定义的普通方法,反而会成为该 Module 的类方法;在 Module#class_eval 中定义的普通方法,反而会成为该 Module 的实例方法。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
110
在线时间
953 小时
注册时间
2007-4-25
帖子
805
76
发表于 2011-1-21 12:27:23 | 只看该作者
本帖最后由 苏小脉 于 2011-1-21 12:28 编辑

这里有一篇 Yuki Sonoda (园田裕贵)的博文:http://yugui.jp/articles/846
其中介绍了三种隐式的上下文:self,klass,常量定义点(这个是我从英语直接翻译过来的)。

下面的概念是直接从该博文中摘抄下来的,如果你能很自在地读英语,那推荐看原文,其中包含了例子代码。

所谓 "klass",是指定义方法(不包括单例方法的定义)的默认(隐式)类,Yuki 称之为 "default definee"(默认被定义者)。比如,在任意处写下一个方法的定义(def foo; end),实际上是定义了某个类的实例方法,这个类就是这里说的 "klass"。Ruby 总是会保存这个类的一个引用,但官方的实现中并没有直接的方法获取这个类。

在 Ruby 顶层,定义一个方法,其 default definee 是 Object 类型。这个可以参考:http://szsu.wordpress.com/2009/11/07/top_level_object_kernel/

当你使用 class 的语法时,在 class ... end 内部会产生一个新的上下文,这时 self 和 default definee 都会指向这个类本身。所以在内部定义的方法就是该类的实例方法,这个大家都知道。

如果你已经在一个方法主体中,那么 self 是这个方法的接收者,而 default definee 则是语法上的方法定义外部的最近的那个类。
  1. class Klass
  2.     def foo
  3.         def bar
  4.         end
  5.     end
  6. end

  7. Klass.new.foo

  8. p Klass.instance_method :bar # => #<UnboundMethod: Klass#bar>
复制代码
这里 foo 也是 Klass 的实例方法。

当然,方法的定义还可以出现在其它地方,但无论在哪儿,都会有一个 default definee。比如 Yuki 给出的这个例子就是在处理方法参数默认值的时候定义的方法,其 default definee 仍然是语法上的外部的 Bar 类:
  1. class Bar; end  
  2. $bar = Bar.new  
  3. class Baz  
  4.   def $bar.hoge(a = (def fuga; end))  
  5.     def piyo; end  
  6.   end  
  7. end  
  8. $bar.hoge  
  9.   
  10. Baz.instance_method(:fuga)      #=> #<UnboundMethod: Baz#fuga>  
  11. Baz.instance_method(:piyo)      #=> #<UnboundMethod: Baz#piyo>  
  12.   
  13. $bar.method(:fuga)              # raises a NameError "undefined method `fuga' for class `Bar'"  
  14. $bar.method(:piyo)              # raises a NameError "undefined method `piyo' for class `Bar'"
复制代码
一句话:class 的定义改变了 default definee,而方法定义不会改变。

博文后半部分是关于 instance_eval 和 class_eval 在操纵 self 和 default definee 上的不同点,这个留待下一贴补完。

-----------------------------------------------------------

一些关于 Yuki Sonoda 的资料:
Yuki Sonoda,“园田裕贵”,是 CRuby 核心开发团队的成员之一,Ruby 社员大多称她为 “Yugui”。她目前负责管理 Ruby 1.9 的发布。
她的个人主页:http://yugui.jp/about/author
Linkedin 主页:http://jp.linkedin.com/in/yugui
Facebook 主页:http://www.facebook.com/yugui
Twitter 主页:http://twitter.com/#!/yugui
一张照片,左:Matz(松本行弘),中:Yuki,右:笹田耕一(Sasada Koichi),此人便是 Ruby 虚拟机 YARV 的作者。
[email protected]:~> repeat 1 fortune
Matz is nice, so we are nice.
回复 支持 反对

使用道具 举报

Lv3.寻梦者

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

贵宾

75
 楼主| 发表于 2011-1-20 09:56:05 | 只看该作者
和其他的语言不一样,Ruby的常量(Constant)可以在初始化后随意改变其置。考虑下面一段代码。


将其保存为 test.rb 然后运行它。




在默认情况下运行它,程序对你说:嗨,老兄,你早已经初始化好了Apple这个常量,当然,他只是警告你,而程序继续运行。我们试试将安全等级设置低一点。ruby.exe 支持一个参数叫做安全等级,表示为 -W[0|1|2]。由于默认是第二等级,verbose,因此我们只需要测试0和1的情况。

当安全等级为0时,他就不发牢骚了。

RM的RGSS/RGSS2系统也不会发牢骚,这就是FSL脚本可以利用常量随时更改配置的原因了。


点评

改常量不是好习惯。  发表于 2011-1-21 11:26
补充:更改常量只能在顶层或类/模块定义中,不能在方法中  发表于 2011-1-20 12:59

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

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-25 07:47

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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