Project1

标题: alias重定义了怎么办…… [打印本页]

作者: Tabris_Air    时间: 2009-3-30 19:36
标题: alias重定义了怎么办……
好像战斗中会随机的出现stack level too deep
这样的错误……

ms是alias多次定义一个函数的问题么?
该怎么办呢…… [LINE]1,#dddddd[/LINE]此贴于 2009-4-3 12:39:26 被版主darkten提醒,请楼主看到后对本贴做出回应。 [LINE]1,#dddddd[/LINE]版务信息:本贴由楼主自主结贴~
作者: 八云紫    时间: 2009-3-30 20:27
自己把那些同名方法整合在一起,不使用 alias 即可
作者: Tabris_Air    时间: 2009-3-30 21:25
呃不太懂…
比如两个脚本里面有:alias 函数A 函数C和alias 函数B 函数C…这样的话应该改哪个呢…?
作者: 八云紫    时间: 2009-3-30 21:39
语法:

alias 新方法名 旧方法名

给方法或全局变量添加别名。可以给方法名指定一个标识符或 Symbol(不能写 obj.method 这样的表达式)。 alias 的参数不会被计算。

给方法添加别名时,别名方法将继承此刻的原始方法。此后,即使原始方法被重新定义,别名方法仍然保持着重定义前的老方法的特性。若您改变了某方法的内容后,又想使用修改前的方法时,别名会非常有用

F1 是这么说的。

旧的方法相当于就与之前的方法定义。

比如
   class A
      def abc
        @a = 1
      end
   end
   class A
      alias old_abc abc
      def abc
        old_abc
        @a += 1
      end
   end

这里的 alias old_abc abc 中的 old_abc 就是之前的方法。

整合的话,就变成
   class A
      def abc
        @a = 1
        @a += 1
      end
   end

这个样子了。

因为每调用一次 alias 的话,都会先把方法地址压栈,所以多调用 alias 的话,堆栈就容易溢出了。(这个是个人理解,可能有误,不过原因大概是这个)

就是这样的喵~~~~~~{/hx}
作者: 八云紫    时间: 2009-3-31 03:02
以下引用新月の道化师于2009-3-30 19:02:00的发言:

这个错误原因是由于循环次数过多导致的,与alias无关,请检查是不是程序中有死循环
偶尔出现说明死循环可能和某个条件分歧有关


循环貌似不占用堆栈的吧?

[LINE]1,#dddddd[/LINE]

另外,Scene 类里都有一个死循环的说。。。
作者: 新月の道化师    时间: 2009-3-31 07:03
以下引用火焰猫燐于2009-3-30 19:02:38的发言:
<BR><SCRIPT language="javascript">
   
strCont="[quote]以下引用新月の道化师于2009-3-30 19:02:00的发言:\r\n\r\n这个错误原因是由于循环次数过多导致的,与alias无关,请检查是不是程序中有死循环\r\n偶尔出现说明死循环可能和某个条件分歧有关 \r\n
\r\n\r\n循环貌似不占用堆栈的吧?\r\n\r\n[LINE]1,#dddddd[/LINE]\r\n\r\n另外,Scene 类里都有一个死循环的说。。。";
document.write(ubb.spbShowTopic(strCont,1));
//-->
</SCRIPT><BLOCKQUOTE class="CodeBorder">以下引用新月の道化师于2009-3-30 19:02:00的发言:<BR>
<BR>
这个错误原因是由于循环次数过多导致的,与alias无关,请检查是不是程序中有死循环<BR>
偶尔出现说明死循环可能和某个条件分歧有关 <BR>
</BLOCKQUOTE><BR>
<BR>
循环貌似不占用堆栈的吧?<BR>
<BR>
<HR noshade="" size="1" color="#dddddd"><BR>
<BR>
另外,Scene 类里都有一个死循环的说。。。

<BR><BR><FONT color="red">[本贴由作者于 2009-3-30 19:15:04 最后编辑]</FONT>
[/quote]
scene的loop是可以通过break跳出的
偶表达错了,偶是说方法的递归调用无法跳出时。。。
$abc = 0
class Test
  def meth1
    $abc += 2
    meth2
  end
  def meth2
    $abc += 2
    meth1
  end
end

a = Test.new
a.meth1
作者: 八云紫    时间: 2009-3-31 07:05
递归 和 alias 都是一样要使用堆栈,所以~~~~
作者: Tabris_Air    时间: 2009-3-31 07:27
我先把alias都整合了……看看会不会还出问题……

话说现在才反应过来,alias只是为了写程序方便么= =
作者: 新月の道化师    时间: 2009-4-1 02:24
以下引用火焰猫燐于2009-3-30 23:05:52的发言:
<BR><SCRIPT language="javascript">
   
strCont="递归 和 alias 都是一样要使用堆栈,所以~~~~";
document.write(ubb.spbShowTopic(strCont,1));
//-->
</SCRIPT>递归 和 alias 都是一样要使用堆栈,所以~~~~

唔,不明白咩,为虾米使用alias会出现堆栈问题?
偶一般都是自己独立写脚本用alias的机会不多不熟悉
作者: 八云紫    时间: 2009-4-1 02:32
alias 在重定义方法的时候要先将就方法的地址入栈的说。
作者: 新月の道化师    时间: 2009-4-1 16:55
以下引用火焰猫燐于2009-3-31 18:32:10的发言:
<BR><SCRIPT language="javascript">
   
strCont="alias 在重定义方法的时候要先将就方法的地址入栈的说。";
document.write(ubb.spbShowTopic(strCont,1));
//-->
</SCRIPT>alias 在重定义方法的时候要先将就方法的地址入栈的说。

额,能否举个alias造成stack too leap的例子咩?
作者: 紫苏    时间: 2009-4-1 18:42
程序运行时,函数代码是保存在进程地址空间的代码段中的,alias 的作用就是将函数复制一份到代码段,或是将全局变量复制一份到数据段中,只不过别名函数复制的是值,而别名全局变量仅仅复制地址~
在程序执行到调用某函数的时候才会操作栈内存,这时会将函数的返回地址和参数信息压入栈中(也就是汇编中的 push 指令),然后执行子程序,函数返回时获取并跳转到之前在栈中保存的返回地址继续执行
所以栈溢出的异常和 alias 复制了多少次函数没有关系,可以做一个测试,程序自动生成几万行 alias xx xx,符号各不相同,看看是否会产生栈溢出就知道了~
有些语言支持在栈上分配内存,比如 c++ 在栈上分配数组,如果数组长度超过了一定限度就会产生溢出……但 Ruby 的数组是堆中动态分配的对象,所以 Ruby 中 stack level too deep 这个异常多半是由于函数嵌套调用或者递归层次太深引起的,就像新月上面说的那样{/hx}
作者: 八云紫    时间: 2009-4-1 20:06
呀,测试了一下,是我理解错了。

道歉~~~~
作者: Tabris_Air    时间: 2009-4-1 20:33
可是话说自从我把与战斗脚本有关的alias全部整合之后……
到现在还没有出现过报错 = =b
不解ing……


以下引用紫苏于2009-4-1 10:42:58的发言:

程序运行时,函数代码是保存在进程地址空间的代码段中的,alias 的作用就是将函数复制一份到代码段,或是将全局变量复制一份到数据段中,只不过别名函数复制的是值,而别名全局变量仅仅复制地址~
在程序执行到调用某函数的时候才会操作栈内存,这时会将函数的返回地址和参数信息压入栈中(也就是汇编中的 push 指令),然后执行子程序,函数返回时获取并跳转到之前在栈中保存的返回地址继续执行
所以栈溢出的异常和 alias 复制了多少次函数没有关系,可以做一个测试,程序自动生成几万行 alias xx xx,符号各不相同,看看是否会产生栈溢出就知道了~
有些语言支持在栈上分配内存,比如 c++ 在栈上分配数组,如果数组长度超过了一定限度就会产生溢出……但 Ruby 的数组是堆中动态分配的对象,所以 Ruby 中 stack level too deep 这个异常多半是由于函数嵌套调用或者递归层次太深引起的,就像新月上面说的那样


作者: 紫苏    时间: 2009-4-1 21:19
整合之后少了一个函数调用的步骤,所以是有区别的~
用 alias 可能出现这样的情况,比如想在原来的 start_phase5 基础上添加功能:
############## 原 RGSS 脚本 ##############
class Scene_Battle                       #
   def start_phase5                       #
     # 原来的 start_phase5                #
     # ...                                #
   end                                    #
end                                      #
##########################################

############## 插件脚本 1 ################
class Scene_Battle                       #
   alias xrxs26_start_phase5 start_phase5 #
   def start_phase5                       #
     # ...                                #
     xrxs26_start_phase5                  #
   end                                    #
end                                      #
##########################################

############## 插件脚本 2 ################
class Scene_Battle                       #
   alias xrxs26_start_phase5 start_phase5 #
   def start_phase5                       #
     # ...                                #
     xrxs26_start_phase5                  #
   end                                    #
end                                      #
##########################################


就会产生 stack level too deep 的异常了——
一开始 xrxs26_start_phase5 复制的是 RGSS 预定义的方法,插件脚本 1 中重新定义 start_phase5,添加新的东西,再执行原来的 start_phase5,至此都没有问题~
接着插件脚本 2 又 alias 了 start_phase5,愿意是想直接沿用旧的 start_phase5,但旧的 start_phase5 已经被插件脚本 2 覆盖为调用 xrxs26_start_phase5,所以在这之后调用 xrxs26_start_phase5 就会再次调用其本身,产生了一个无限循环……
虽然归根究底还是无限递归层次的问题,不过还是多少和 alias 有关系,上面说的不太准确,纠正下~ [LINE]1,#dddddd[/LINE]系统信息:本贴由楼主认可为正确答案,66RPG感谢您的热情解答~
作者: 新月の道化师    时间: 2009-6-12 08:00
这个错误原因是由于循环次数过多导致的,与alias无关,请检查是不是程序中有死循环
偶尔出现说明死循环可能和某个条件分歧有关




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