Project1

标题: update_all_windows方法看不懂... [打印本页]

作者: 九靈    时间: 2014-8-5 22:04
标题: update_all_windows方法看不懂...
RUBY 代码复制
  1. def update_all_windows
  2.     instance_variables.each do |varname|
  3.       ivar = instance_variable_get(varname)
  4.       ivar.update if ivar.is_a?(Window)
  5.     end
  6.   end



instance_variables  
这是...局部变量?
话说她在哪被赋值的?

ivar
这是局部变量吧?

instance_variable_get
似乎是Ruby的

ivar.update if ivar.is_a?(Window)
这是Window类的update吧?
Base、Selectable...

作者: 喵呜喵5    时间: 2014-8-5 22:19
本帖最后由 喵呜喵5 于 2014-8-5 22:24 编辑

instance_variables
以字符串数组的形式返回对象中所有变量的名字。
  1. obj = Object.new
  2. obj.instance_eval { @foo, @bar = nil }
  3. p obj.instance_variables
  4. # => ["@foo", "@bar"]
复制代码
instance_variable_get(var)
获取并返回该对象的实例变量。
其中的参数 var 必须是字符串或者 Symbol 符号 的形式。
如果目标变量没有被定义,则会返回nil。
@foo  【防止代码被修改的措施,请无视本行
  1. class Foo
  2.   def initialize
  3.     @foo = 1
  4.   end
  5. end
  6. obj = Foo.new
  7. p obj.instance_variable_get("@foo")     # => 1
  8. p obj.instance_variable_get(:@foo)      # => 1
  9. p obj.instance_variable_get(:@bar)      # => nil
复制代码
如方法名一样,这个方法执行的内容就是调用对应Scene中所有属于Window类或是其子类的实例变量的update的方法   
作者: 九靈    时间: 2014-8-5 23:17
本帖最后由 九靈 于 2014-8-5 23:19 编辑
喵呜喵5 发表于 2014-8-5 22:19
instance_variables
以字符串数组的形式返回对象中所有变量的名字。instance_variable_get(var)
获取并返 ...


所以是省了self 咯!


def update_all_windows
    self.instance_variables.each do |varname|
       ivar = self.instance_variable_get(varname)
       ivar.update if ivar.is_a?(Window)
   end
end

是这样吧?

像是...  Scene_Title.instance_variables.each do |varname|

作者: taroxd    时间: 2014-8-6 07:23
本帖最后由 taroxd 于 2014-8-6 07:30 编辑
九靈 发表于 2014-8-5 23:17
所以是省了self 咯!


def update_all_windows


前两个红字是对的,第三个红字是错的

当前的 self 并不是指 Scene_Title ,而是 Scene_Title 的一个实例

想要理清一下 self 的值,你可以随时往代码里加一句 p self 来检测,也可以参考一下 https://rpg.blue/thread-108581-1-1.html 的第二、第三节进行学习(有一点点难度!)

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

当你找到一个类似局部变量的名字,但不是局部变量的时候,都是省略 self 的调用方法。当这个方法在预设脚本中还找不到的时候,请参考 F1手册 和 Ruby文档


作者: 九靈    时间: 2014-8-6 08:16
本帖最后由 九靈 于 2014-8-6 08:19 编辑
taroxd 发表于 2014-8-6 07:23
前两个红字是对的,第三个红字是错的

当前的 self 并不是指 Scene_Title ,而是 Scene_Title 的一个实例 ...


Scene_Title的实例有[:@viewport, :@sprite1, :@sprite2, :@foreground_sprite, :@command_window]

所以是@command_window.instance_variables.each do |varname|这样?
还是:@command_window.instance_variables.each do |varname|这样?
作者: DeathKing    时间: 2014-8-6 08:18
看来URG3还讲得不够清楚,由于涉及到了元编程的一些东西,我想略过去,仅仅是让大家关注代码【做了什么事儿】。

instance_variables 是一个元编程方法,用于获得当前上下文(Context)中的实例变量,当然返回的是由符号构成的数组。URG3 0.0.3的附录后面附带了少部分用作反射机制的元编程方法,有兴趣的同学不妨一看。

ivar是局部变量,其值是instance_variable_get(varname)的返回值。由于符号这个东西是自求值的(对其求值就是它本身),而我们想计算 符号→值 这个映射,在运行时想要执行这个动作就要利用元编程的手段,强制让解释器再进行求值(evaluate)。要解释元编程,需要解释太多东西了,所以我希望大家暂时略过……至于大家对于符号的疑惑,是源于不太清楚符号这个东西的历史背景,和为什么要引入这个东西……稍后我会整理一下这方面的知识。

至于ivar.update if ivar.is_a?(Window),如果ivar直接所在的类定义了update方法,那么就执行该类的方法,否则就向父类继续搜索update方法,由于Window类定义了update方法,所以这句代码不会引发“NoMethodError”

之前曾经翻译过《Ruby中的元编程》系列小讲座,不妨一看:https://github.com/DeathKing/metaprogramming-in-ruby

Paolo Perrotta所著的《Ruby元编程》也被翻译并出版了,该书深入地剖析了Ruby的元编程,具有使用价值,值得一看。

作者: taroxd    时间: 2014-8-6 08:24
本帖最后由 taroxd 于 2014-8-6 08:34 编辑
九靈 发表于 2014-8-6 08:16
Scene_Title的实例有[:@viewport, :@sprite1, :@sprite2, :@foreground_sprite, :@command_window]

所以 ...


[:@viewport, :@sprite1, :@sprite2, :@foreground_sprite, :@command_window]
这是 Scene_Title 的实例所有实例变量的名称构成的符号数组(有点绕口,用颜色断句)

Scene_Title 的实例就是一个通过 Scene_Title.new 生成的东西,具体生成的时间就在你上一个提问,那个 first_scene_class 的问题里面
作者: 九靈    时间: 2014-8-6 08:42
taroxd 发表于 2014-8-6 08:24
[:@viewport, :@sprite1, :@sprite2, :@foreground_sprite, :@command_window]
这是 Scene_Title 的实例 ...

p ivar



这就是  符号→值  的映射结果吗

self.instance_variables  #=> :@command_window

ivar = instance_variable_get(:@command_window)




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