Project1

标题: 【新手互助】利用Mix-in(糅合)构建低耦合脚本 [打印本页]

作者: 独孤残云    时间: 2010-8-19 12:51
标题: 【新手互助】利用Mix-in(糅合)构建低耦合脚本
写在最前:以下观点来源于新手对RGSS脚本系统的一些浅显认知,希望能够给其他新手一些启发;牛人请直接跳过。如感觉不妥,请善意的指出;对于自认为很牛的无故拍砖者,一律鄙视!
原文链接:http://rpg.blue/home.php?mod=spa ... id=47826&id=689

include(module ... ) 对指定模块的性质(方法或常数)进行添加。返回 self。include 正是为实现 Mix-in(糅合)功能而设计的,而 Mix-in 取代了多重继承。
以上为RM中针对于关键字include的官方解释,本篇后续的内容亦是围绕此关键字展开。
Train_Actor是我接触RGSS以来遇到的第一个脚本系统,原帖可参见本坛脚本库,我空间里也有。用过的人应该都知道,只要借助于它便可轻易的实现角色跟随的特效。而引入此脚本的方法也很简单,只要在Main之前插入一段新脚本页,全部内容Copy即可。可谓便捷、经典。

第一次用这个脚本的时候觉得很神奇:该脚本完全独立,而系统是如何在恰当时机自动调用这个新增脚本内部方法的呢?经过一些简单的验证之后,终于渐渐发现了问题所在。

不知大家有没有留意到,该脚本的末端,也就是在module Train_Actor声明完毕之后,还有如下代码:

class Game_Party
include Train_Actor::Game_Party_Module
end
class Game_Player
include Train_Actor::Game_Player_Module
end
class Spriteset_Map
include Train_Actor::Spriteset_Map_Module
end
class Scene_Map
include Train_Actor::Scene_Map_Module
end

结合官方对于include的解释,不难猜想,这种独立脚本的自动调用机制即是由此而来。

所谓“对指定模块的性质(方法或常数)进行添加”,简单而言,也就是让自己脚本中已定义模块的方法或常数,成为指定模块中相应方法的逻辑补充。即是说,系统在调用原有模块内部方法的同时,会自动对已经被include至该模块的其他模块内部方法或常数进行调用。

有点绕口,我们不妨作如下实验来说明问题:

Main之前插入一个新脚本页,名字随便,而后写入如下代码:

module TestInclude
    def update
    p "外部方法被调用"   #验证一下自己的方法是否被调用
    super
    end
end
class Game_Player
    include TestInclude
end

代码很简单也很好理解,定义一个名为TestInclude的模块,此模块内部含有一个update方法,之后我们将此模块include至Game_Player模块,这样一来,系统对Game_Player的update方法调用完毕之后将自动调用TestInclude里的update——也就是说,我们自己模块中的方法成为了系统自带的Game_Player模块中update方法的逻辑补充。

点F12执行,则带有“外部方法被调用”字样的对话框会弹出。由于系统对于Game_Player里的update是一直调用的,因此我们自己模块里的update也会一直向外弹对话框,从任务管理器里将Game.exe扼杀掉即可。

之前也看过神思大人写的战斗CP脚本系统,有很多新人反应不知道该怎样引入自己的工程。我想如果借助于这种方法,神思大人完全可以将自己的CP系统也改装成不依赖于原有系统脚本且随用随引的独立系统了。

至于官方注释中提到的多重继承,这是C++中一种稍复杂的机制,这里不再讨论。其实在本人看来,Mix-in更像是多重反向继承。大家细心的话,应该就可以发现,对于include的外部模块,系统是优先调用原模块的方法,而后调用include模块中的方法,与C++中继承机制的调用顺序相反。
作者: 六祈    时间: 2010-8-19 12:55
对于include的外部模块,系统是优先调用原模块的方法,而后调用include模块中的方法,与C++中继承机制的调用顺序相反。
独孤残云 发表于 2010-8-19 12:51

如果按照你的说法,那么调用update时就该调用原类里的方法,那么外部模块的update并不会被调用

作者: 独孤残云    时间: 2010-8-19 13:11
回复 六祈 的帖子
C++中的继承机制通常体现为:子类重写方法--->基类方法
Ruby中的include体现为:原有方法--->补充方法
如果
class A
include module B
End
按文中的说法,我是将B视为A的子类,其实这种说法可能并不是很严密。
六祈大人如果觉得有什么不妥,不妨将Game_Player.update()方法也加一句p输出,一试便知。

   
作者: 六祈    时间: 2010-8-19 13:26
回复 独孤残云 的帖子
呵呵,你学过C++,其实结合ruby能产生很多新的思路

但是呢,ruby的mix-in可能和你臆测的有所出入

mix-in其实不太像继承,由module带入的方法并不是super或者sub,而是以定义的先后来确定的

比如
module A
def a
p "i\'m module method"
end
end

class B
include A
def a
p "i\'m B\'s method"
end
end

B.new.a                       #i'm B's method

class C
def a
p "i\'m C\'s method"
end
include A
end

C.new.a                   #i'm module method




以上
所以如果是在类定义完之后
class SomeClass
include SomeModule
end

模块的同名方法就会覆盖类的方法
   
作者: 独孤残云    时间: 2010-8-19 13:33
回复 六祈 的帖子
六祈大人说的很对,我同意你的观点。
文中的最后一段意在补充说明官方解释的后半句,至于我本人,本来就没打算将二者并立而论。
第三帖只是对六祈大人以最后一句论事发第二帖的回复。还望莫要误解~

   
作者: 独孤残云    时间: 2010-8-19 13:35
回复 六祈 的帖子
另,我C++并非只是“学过”,如果六祈大人有时间,我们可以好好切磋一番~

   
作者: 紫苏    时间: 2010-8-19 13:53
这个机制确实可以用来实现多继承的工程,和 Java、C# 的接口是相同的概念
在 Ruby 中,一个模块 A 包含另一个模块 B 后,模块 B 中的常量、类变量和实例方法会被绑扎到一个匿名模块中,并隐式地让模块 A 继承自这个匿名模块,所以如果在 Mix-in 的时候模块 A 中已经有了模块 B 中的实例方法,就会出项方法的覆盖,而在该方法中通过 super 就能调用父模块中的同名方法;然而如果子模块 B 中的该实例方法并没有调用 super,这个实例方法就不会调用匿名父模块的同名方法
楼主给的这个例子里之所以 TestInclude 的 update 被调用,是因为 Game_Player#update 里调用了 super。可以在 Game_Player#update 里的 super 前后分别插入 p 1、p 2,就不难验证上述理论。这种方法在 RGSS 默认类中的默认实例方法有 super 的情况下十分好用,但如果没有 super,就无法实现所谓的“糅合”了
大家细心的话,应该就可以发现,对于include的外部模块,系统是优先调用原模块的方法,而后调用include模块中的方法,与C++中继承机制的调用顺序相反。

这个取决于 super 在原方法主体前还是后,甚至可能在中间,所以谈不上绝对的先后顺序
作者: 逸豫    时间: 2010-8-19 14:12
本帖最后由 逸豫 于 2010-8-19 14:15 编辑

无视我……我是来乱入的……
恩……那啥不是叫做混成么……
那个……之所以方法被重定义是因为include是在方法定义后才对……

其实汝这样做貌似Game_Player的Update不会执行……执行的是Game_Player的父类Game_Character的update方法……对于方法的增添我们更常使用的是alias

有关alias更详细的说明请PIA这里
作者: 紫苏    时间: 2010-8-19 14:44
回复 逸豫 的帖子

include 在前还是在后无所谓,被 include 的模块中的东西是被捆绑到匿名父模块中的,而并没有替换当前模块中的同名方法:
  1. module A
  2.   def foo
  3.     p 1
  4.   end
  5. end

  6. class C
  7.   def foo
  8.     p 2
  9.   end
  10.   include A
  11. end

  12. c = C.new
  13. c.foo          # 2
复制代码
Game_Player#update 是执行了的,其内部通过 super 调用了 TestInclude#update,而  TestInclude#update 又通过 super 调用了 Game_Character#update
作者: 红灯    时间: 2010-8-19 14:54
现在还比较少接触include,看完这个似乎有点懂了,几位大人能否详细说明下其与super间的区别么?
作者: 独孤残云    时间: 2010-8-19 19:25
回复 紫苏 的帖子
原来如此,所以说系统中一些原有的类才是真正的子类,而其内部也早就留有super关键字以供新增基类的扩展吗?多谢紫苏~ 受教了~

   
作者: 独孤残云    时间: 2010-8-19 19:32
回复 红灯 的帖子
Super关键字最早见于java中,用于子类方法执行完毕之后自动调用基类方法。而关键字include,可以指定一个新增的模块成为旧有模块的基类,这样一来,RM在执行原有方法的同时会自动调用我们自己写的方法。使用这种方法可以将自己写的脚本与原系统的耦合度降到最低~

   
作者: IamI    时间: 2010-8-19 20:20
Ruby无接口也无多继承,所以用一个模块的include来达成多继承性。
现在来看,Mix-in的模块大多数都是接口协议(比如Comparable)
但是我想说,在大量使用全局变量的情况下,RM脚本已无低耦合性可言。
作者: 独孤残云    时间: 2010-8-19 21:18
本帖最后由 独孤残云 于 2010-8-23 13:10 编辑

回复 IamI 的帖子
解决问题并非一定要依赖于全局变量,尤其不要在新增脚本中再度引入额外的全局变量,以供系统原有脚本调用。全局变量本身就是耦合的主要来源。
另外,我的目的是“将自己写的脚本与原系统脚本的耦合度降到最低”,而不是深入剖析系统原有脚本间的耦合度高低~呵呵~
抱歉,6R是我接触的第一个不允许连帖的论坛,总是不经意就……

   
作者: BBBBB6    时间: 2010-8-19 21:44
事件党的会心一瓢.
多谢LZ共享,我以后也要学学脚本....不过快中考了555初三是不可能的了...
作者: 红灯    时间: 2010-8-19 22:08
受教了,多谢各位前辈。赶紧做笔记。
作者: 紫苏    时间: 2010-8-20 06:10
本帖最后由 紫苏 于 2010-8-20 06:15 编辑

回复 独孤残云 的帖子

原有的类内部有 super 是因为这个类的方法需要调用基类的方法,比如 Game_Player#update 里有 super 是因为还需要调用基类 Game_Character 里的同名方法,这时在 Game_Player 里 mixin 就相当于在继承链中的 Game_Player 和 Game_Character 之间插入了一个新的节点(匿名类),Game_Player 是它的子类,Game_Character 是它的基类,而如果这个节点的同名方法本身也调用 super,那就会依然调用 Game_Character#update ^_^

显然没有爸爸的类就不能这么做了,比如各种场景类,即便把同名的方法绑扎到模块中糅合进去,由于原场景类里没有 super,模块中的同名方法仍然不会被调用
作者: 八云紫    时间: 2010-8-20 11:18
本帖最后由 八云紫 于 2010-8-20 11:27 编辑

  1. module A
  2. def a
  3. p "i\'m module method"
  4. end
  5. end

  6. class B
  7. include A
  8. def a
  9. p "i\'m B\'s method"
  10. end
  11. end

  12. B.new.a                       #i'm B's method

  13. class C
  14. def a
  15. p "i\'m C\'s method"
  16. end
  17. include A
  18. end

  19. C.new.a                   #"i\'m C\'s method"
复制代码
六祈的例子在 VX 的运行会变成这样,无论如何都只调用原类的方法,很奇怪。
紫苏大的也一样。

系统不同??

回复 红灯 的帖子

include 给我的感觉就是 类似单纯的复制粘贴,把模块里的全部东东复制一份,贴到 include 所在的地方,感觉上和 C 里的 #include 类似。

super 使用在有继承关系的类中,当子类需要使用已经定义好的父类的同名方法的时候,可以加 super 。
作者: 独孤残云    时间: 2010-8-23 08:35
本帖最后由 独孤残云 于 2010-8-23 08:44 编辑

回复 六祈 的帖子
关于六祈大人“我想IamI所说的是默认脚本中已然使用了大量的全局变量。此类常识性问题,你总该先花点时间看一看吧”的说法……
请六祈大人事先考虑清楚,系统中原有脚本的全局变量是否会对新脚本的低耦合度带来影响。注:我这里所说的低耦合度,当然是指新增脚本相对于原系统自带脚本的低耦合。
新手,只不过是相对于Ruby语法而言;至于软件工程中的基本理论,我多少还是有点自信的。另,当认定他人连“常识性问题”都没搞明白时,请事先考虑自身说法有无疏漏,否则结论一旦被推翻,后果是很尴尬的。


   
作者: 独孤残云    时间: 2010-8-23 12:27
本帖最后由 独孤残云 于 2010-8-23 12:33 编辑

回复 六祈 的帖子
在六祈大人怀疑我“常识性问题”没弄明白之前,希望您能回答我几个问题:
1.Train_Actor脚本源码您是否详细看过?
2.Train_Actor中举不胜举的以$为前缀的全局变量您是否注意到过?
3.将此脚本加入到系统或者从系统剔除是否影响原有脚本的正常运行?
如果您这几个问题都能回答上来,但依然没明白我的意思,请恕本人【真】的无能为力。


   
作者: 独孤残云    时间: 2010-8-23 12:32
本帖最后由 独孤残云 于 2010-8-23 12:35 编辑

回复 紫苏 的帖子
谢谢紫苏的提点,以后如果遇到Ruby中的一些高级机制,我会再向你请教的~

   
作者: 分子轨道理论    时间: 2010-8-23 12:35
LZ你要淡定 TRAIN_ACTOR这个东东
关键的是它的算法 和 思路,这才是最重要的
为了一个include。。。。。。。
作者: 独孤残云    时间: 2010-8-23 12:38
回复 分子轨道理论 的帖子
谢谢分子兄提醒,是我太较真了^_^
不过,我是真的很希望六祈版主能明白里边的道理,绝没有别的意思~


   
作者: 六祈    时间: 2010-8-23 12:41
本帖最后由 六祈 于 2010-8-23 12:44 编辑

回复 独孤残云 的帖子
我没其它特别好说的了,就引用IamI的原话吧
但是我想说,在大量使用全局变量的情况下,RM脚本已无低耦合性可言。
IamI 发表于 2010-8-19 20:20



另外你的意思我很明白,添加脚本时不要使用全局变量么

但IamI显然是说默认脚本已经使用了诸如$game_xxxx,$data_xxxx等等大量的全局变量


再回到帖子的主题:

紫苏大人说mixin是引入匿名的父模块,于是愚者想到原类的super方法将会因此而混乱,这个问题该如何解决呢
作者: 独孤残云    时间: 2010-8-23 12:58
回复 BBBBB6 的帖子
如果事件能够用的很熟练的话,也是非常了不起的~接口回调也只是虚拟了事件特性的一部分,两者基本各有利弊吧~
你今年只有中三吗?如果喜欢做游戏的话,有机会可以好好发展一下自己的兴趣爱好,绝对会很有前途的~ 呵呵~


   
作者: 独孤残云    时间: 2010-8-23 13:24
回复 六祈 的帖子
呵~ 解决方法,紫苏的帖子中已经阐述的很清楚了~
另外,能否把您写的“原类的super方法将会因此而混乱”的代码贴给我看看?


   
作者: 六祈    时间: 2010-8-23 13:33
本帖最后由 六祈 于 2010-8-23 13:36 编辑

回复 独孤残云 的帖子
比如:
class Father
def hello
p "father"
end
end

class Son < Father
def hello
p "son"
super
end
end

这时候Son.new.hello就会p出son和father

然后

module Another_Father
def hello
p "not my father"
end
end
class Son
include Another_Father
end

这时候Son.new.hello就会p出son和not my father

也就是说,原类里定义的super失效【这个失效用词不严谨请勿吐槽,意指效果并非所希望的】了
作者: 独孤残云    时间: 2010-8-23 13:47
本帖最后由 独孤残云 于 2010-8-23 13:50 编辑

回复 六祈 的帖子
p "not my father"
该行后面再追加一句super——紫苏的帖子中明明已经说的很清楚了吧?

代码如下:
class Father
def hello
p "father"
end
end

class Son < Father
def hello
p "son"
super
end
end

module Another_Father
def hello
p "not my father"
super
end
end
class Son
include Another_Father
end


@son=Son.new
@son.hello

exit #结束程序

运行结果:
son ---- not my father ---- father

这个是六祈大人想要得到的结果吗?
   
作者: 六祈    时间: 2010-8-23 13:56
回复 独孤残云 的帖子
见树只是树么?

如果原方法没有super怎么办?这样的话写每一个include的module的方法还要去看原类的方法,如果原方法没有父类,而你的module方法写入了super,也很麻烦
作者: 逸豫    时间: 2010-8-23 17:11
  1. class Ruby
  2.   def writer
  3.     print "Matz"
  4.   end
  5. end
  6. #假设以上是默认脚本,为了游戏的良好兼容性,严禁修改
  7. module C
  8.   def writer
  9.     print "Dennis M Ritchie"
  10.   end
  11. end
  12. class Ruby
  13.   include C
  14. end
  15. Ruby.new.writer # => Matz

  16. #好吧,这样的话新定义的模块C就不能起到作用了,即:对于原方法中没有super的方法,不能使用添加模块中同名方法的方法来修改

  17. class Ruby
  18.   alias new_writer writer
  19.   def writer
  20.     new_writer
  21.     super
  22.   end
  23. end

  24. Ruby.new.writer # => Matz & Dennis M Ritchie
复制代码
汝等还在讨论啊- -
这不是很清楚了么……module方法只能在原方法中有super语句时才能用,否则需要手动添加一句super
作者: DeathKing    时间: 2010-8-23 17:16
为了解决“多继承”而提出来的“混成”,至于这么纠结么?
作者: 独孤残云    时间: 2010-8-23 17:46
本帖最后由 独孤残云 于 2010-8-23 19:44 编辑

呵~ include的机制,请参见紫苏的帖子。
这不过是我接触的第一个高级关键字,当然不是万能的。至于挑毛病挑到Ruby语言本身,我说过了,无故拍砖者一律鄙视。
另,帖子里标明了是【新手互助】,本来就是写给新人看的,能得到各位版主的指导固然很好,至于一句一句的推敲就免了,经不起、也不值得。
有劳版主大人把帖子沉了吧~
作者: BBBBB6    时间: 2010-8-23 19:52
回复 独孤残云 的帖子
决定了!要好好学脚本!多谢各位~88~

   
作者: 独孤残云    时间: 2010-8-23 19:56
回复 BBBBB6 的帖子
呵~ 好好加油啊~ 大家一起努力!!

   
作者: BBBBB6    时间: 2010-8-23 19:58
回复 独孤残云 的帖子
我可是只知道条件分歧的脚本啊。。。从头开始呢。。。有没有什么好的教程推荐啊。。。

   
作者: 独孤残云    时间: 2010-8-23 20:12
回复 BBBBB6 的帖子
DeathKing版主的个人签名里推荐的:http://rpg.blue/misc.php?mod=faq,好像挺不错的。话说我也是刚刚开始摸索的。
不要着急,先慢慢来吧~

   
作者: 独孤残云    时间: 2010-8-23 20:26
回复 DeathKing 的帖子
版主大人莫要误会,我绝没有要针对谁的意思~ 只不过会不习惯随随便便就被人认定缺乏“基本常识”。
对于Ruby中很多机制的理解都还留有C++的影子,这些东西以后会记得跟您多多请教的~

   
作者: 六祈    时间: 2010-8-23 20:49
回复
谢谢分子兄提醒,是我太较真了^_^
不过,我是真的很希望六祈版主能明白里边的道理,绝没有别的意思~
...
独孤残云 发表于 2010-8-23 12:38

绵里藏针话中带刺不是讨论的做法,如果你对愚者有何不满可以直说,版主的权限愚者只会依版规而用
希望xxx明白这种话说起来似乎是愚者不懂而您懂了【应该没曲解吧】,既然说这样的话又何必惺惺的说绝没有别的意思呢?

回到我一开始触痛您的话,愚者说您没有基本常识,理由如下:
IamI说rm脚本天生的大量使用了全局变量,已无耦合性可言
【诚恳的说,愚者不是软工的,也不懂耦合度,于是大致理解为代码的相互依赖度和侵入度,如若有误,请指出】
对于一个翻过几遍F11的人来说,应该是懂得$data_xxx和$game_xxx这些的,几乎充斥了整个游戏的全部进程
既然你说怎么做不到低耦合度,于是愚者很简单的理解为您没怎么浏览过F11的默认脚本【ok,愚者之前那句的观点仅仅在此,如果有错,向你道歉】

【回到帖子的主题】把我想表达的意思全部写出来:
写脚本,低耦合度意味着更少的整合和调试
于是要做到:
【对原脚本的破坏性要小】
【与其它脚本兼容性要好】
后面说到super调用的问题,对于原类没有的方法,混入模块就能获得方法,这个最简单,但是有时候难免会因为其它脚本的缘故而导致命名被占。

已有的方法要用super来调用混入模块的方法,而混入模块的方法又要用super来调用原父类的方法

如果只是默认脚本的基础上加入一个人的混入模块,还可以通过一一查看原类是否已有方法来解决。如果是在其它脚本师的脚本之后加入呢?【有没有同名方法,有的话那么有没有super,没super同名方法等于没写,有super不写就完了。没有同名方法写了super又是悲剧】这个需要考虑的东西数量会很多

这些就是后面我想表达的关于include的潜在问题【也许是因为愚者才疏学浅】。

另外这样的看法是相对alias而来的,alias的技巧从设计模式的角度来讲,应该算装饰器模式,每个脚本师都可以在之前的基础上添加自己的语言而不会和其它脚本师的脚本冲突【或者说不容易】

以上为愚者拙见,望楼主不吝赐教
作者: 不如归去    时间: 2010-8-23 21:09
本帖最后由 不如归去 于 2010-8-23 21:15 编辑

”新手讨论“不是各种幼稚思想的挡箭牌。
作者: 独孤残云    时间: 2010-8-23 21:28
本帖最后由 独孤残云 于 2010-8-23 21:29 编辑

回复 六祈 的帖子
呵~ 多谢六祈大人这样给足一个新手面子~
之所以写这个的目的,最初只是因为看到很多新人在神思大人的CP系统下跟帖,询问除了引入新脚本之外还需要做哪些改动。所以提供一点参考意见,方便自己也方便别人。
帖子的内容一开始就旨在讨论如何降低自己新增的脚本与原脚本系统间的耦合,说白了,就是写出的系统能让一个用它的新手简简单单引入一个新脚本页即可,而并非讨论整个RGSS系统耦合度的高低问题。单就这一点,我相信我明白,很多人也都明白,但您确确实实没明白。
如果您认为Ruby新手的身份不足以与您一起品头论足,那我可以告诉您,很多编程语言都具备类似的共通点,至于全局变量,更是C++基本中的基本。所以,请不要随随便便以老手的身份认定Ruby新手同样会缺乏基本常识。
至于“绵里藏针”,呵~人本身便是棉针一体,可以针对一部分人来保护自己,但却不能误伤无辜的人,这个道理,六祈大人应该明白吧?
最后,您大力推荐的alias,我只能尽自己的努力去研究,然后尽可能的分享一点自己的破陋见解。六祈大人很强,这点我深信不疑,如果能得到您的指导,我当然高兴。但我还是那句话,新手的东西,不可能经得住一句话一句话的推敲,希望能理解。至于Ruby机制本身存在的缺陷,反正我是无能为力的。

   
作者: 独孤残云    时间: 2010-8-23 21:31
本帖最后由 独孤残云 于 2010-8-23 21:34 编辑

回复 不如归去 的帖子
说的有道理,但请您看在一个新手公开了自己仅有的一丁点经验的前提上加以谅解,可以吗?虽然那对您这样的高手而言是不值一看的破玩意儿。


   
作者: 独孤残云    时间: 2010-8-23 21:49
回复 六祈 的帖子
抱歉,六祈大人,或许是因为我始终没能摆脱6R给我的第一印象……带给您的麻烦,在此深表歉意……
不过,我很希望新手也能拥有自己的发言权,而不是仅仅只有在牛人后边跟帖或是当伸手党甚至于潜水党的份……
不如归去说的很对,正是因为有了先前被人鄙视的经验,所以才举起了这样的挡箭牌,但不是心安理得,而是一种无奈……
大家最初都是从新手的状态一点一点进步至今的,谁都有过幼稚的时候,如果能看到自己从前的影子,请试着相互谅解……

   
作者: IamI    时间: 2010-8-23 21:50
累计连贴多次,算上以前的一共50分,先记着,又发现的话一并算账;
看来是我的话引起了这一论战,那么抱歉。
我希望您要认识的是:在现代OOP当中,低耦合性显然是程序员们所追求的目标。
不可否认的是,本地C++由于其本身的特性,耦合性显然无法到达现代编程的安全要求的标准。全局性的友元方法和变量构成不安全的因素。
Ruby中作为规避高耦合性带来的风险,提供的方法为:用include方法进行的常量封装和alias进行的方法改造,甚至提供了安全系数$SAFE进行保护。
但是RGSS默认脚本所使用的大量全局变量已经破坏了Ruby的这一特性。
目前通行标准是:常量内部定义,或者Module封装include,方法用alias或者直接重写。

此帖不封,留待讨论。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1