Project1

标题: RUBY问题收集帖 [打印本页]

作者: 雷欧纳德    时间: 2006-12-20 15:32
标题: RUBY问题收集帖
说明部分:

1、该帖子用于收集一些不常用的,但在有的情况下又比较重要的一些问题,主要针对ruby语言,不是局限于rgss。比如:什么是迭代器、是什么块、怎么重定义模块方法、pack怎么用等。

2、只要是这些问题你有什么不明白的,可以在这里提出来,我或者其他人会尽力解决。当然你觉得比较好了,也可以说出来和大家分享。

3、普通的关于rm中脚本的一些问题,比如菜单什么的就不要在这个帖子里问了,直接在技术区or新人区发问就行,灌水等会被删除帖子。


问题集:

作者: 雷欧纳德    时间: 2006-12-20 15:32
标题: RUBY问题收集帖
说明部分:

1、该帖子用于收集一些不常用的,但在有的情况下又比较重要的一些问题,主要针对ruby语言,不是局限于rgss。比如:什么是迭代器、是什么块、怎么重定义模块方法、pack怎么用等。

2、只要是这些问题你有什么不明白的,可以在这里提出来,我或者其他人会尽力解决。当然你觉得比较好了,也可以说出来和大家分享。

3、普通的关于rm中脚本的一些问题,比如菜单什么的就不要在这个帖子里问了,直接在技术区or新人区发问就行,灌水等会被删除帖子。


问题集:

作者: 美兽    时间: 2006-12-20 16:58
yield 是什么意思,上次叶子说过一回,但似乎我理解上有出入,RGSS里这个东西一直没完全理解.
作者: 雷欧纳德    时间: 2006-12-20 17:17
以下引用美兽于2006-12-20 8:58:02的发言:

yield 是什么意思,上次叶子说过一回,但似乎我理解上有出入,RGSS里这个东西一直没完全理解.


其实在ruby里,yield就是实现迭带器的,比如Array里的each什么都是通过这个来实现的。
首先,yield必须和块连用,块就是跟在方法后面的{},可以暂时理解为参数也行。比如:
def test
  yield
  yield
end

test{p 'test'}

会p两次 test。现在来解释下这个方法的运行:首先调用方法,然后接着到后面的{},但这里不会运行,而直接进入方法里面,也就是执行yield,而yield就是使先前的块执行,也就是{}里的内容,所以p了两次test。
然后这种:
def test
  yield(1)
end
test{|i| p i}
yield带参数的,执行的时候就会把参数传递给||中间这个变量,然后执行块。

所以,现在我们来定义Array的each方法就是这样:
  def each
    for i in 0...size
      yield(self)
    end
  end

最后,block_given?这个可以判断方式是否带块,这样使用:
def test
  if block_given?
    yield
    p 'block'
  else
    p 'noblock'
  end
end
test{}
test
作者: Melodia    时间: 2006-12-20 17:24
提示: 作者被禁止或删除 内容自动屏蔽
作者: 雷欧纳德    时间: 2006-12-20 17:36
以下引用Melodia于2006-12-20 9:24:50的发言:

不厌其烦地再不好意思地问句:
....为什么我建立新的rb文件时..总是一打开就立刻关闭掉...

呃 `` 怎么可能 `` 什么编辑器呢 `` 不行直接记事本保存为.rb也可以咯..{/gg}

ps:orz这个马甲....
作者: simounF    时间: 2006-12-20 18:04
提示: 作者被禁止或删除 内容自动屏蔽
作者: 亿万星辰    时间: 2006-12-20 18:06
传数组的话……直接把数组写在参数里就行了吧……{/fd}
作者: 雷欧纳德    时间: 2006-12-20 18:40
以下引用simounF于2006-12-20 10:04:41的发言:

API可以传送的参数有哪些,如果想要传些复杂的参数(如数组)该用什么方法

好像同一方法重定义多次(把RTAB多复制几份)会发生栈深度过深的错误,这是为什么

特殊方法是什么意思,有什么用处

1、参数可以是  l i p v  分别是 长整型、整型、字符指针、空
2、
class Array
  
  alias o []
  def [](key)
    o(key)
  end
  
end
然后执行 F12,分析下为什么会出这样的错误?
3、特殊方法?指的哪些?{/gg} 列举几个看看。。
作者: simounF    时间: 2006-12-20 19:00
提示: 作者被禁止或删除 内容自动屏蔽
作者: 美兽    时间: 2006-12-20 19:25
以下引用灼眼的夏娜于2006-12-20 9:17:19的发言:


以下引用美兽于2006-12-20 8:58:02的发言:

yield 是什么意思,上次叶子说过一回,但似乎我理解上有出入,RGSS里这个东西一直没完全理解.




其实在ruby里,yield就是实现迭带器的,比如Array里的each什么都是通过这个来实现的。
首先,yield必须和块连用,块就是跟在方法后面的{},可以暂时理解为参数也行。比如:
def test
yield
yield
end

test{p 'test'}

会p两次 test。现在来解释下这个方法的运行:首先调用方法,然后接着到后面的{},但这里不会运行,而直接进入方法里面,也就是执行yield,而yield就是使先前的块执行,也就是{}里的内容,所以p了两次test。
然后这种:
def test
yield(1)
end
test{|i| p i}
yield带参数的,执行的时候就会把参数传递给||中间这个变量,然后执行块。

所以,现在我们来定义Array的each方法就是这样:
def each
   for i in 0...size
     yield(self)
   end
end

最后,block_given?这个可以判断方式是否带块,这样使用:
def test
if block_given?
   yield
   p 'block'
else
   p 'noblock'
end
end
test{}
test


[本贴由作者于 2006-12-20 9:35:08 最后编辑]



谢谢了.{/ll}
作者: 雷欧纳德    时间: 2006-12-20 19:37
呃 ``` 那些特殊方法就素 属于某个对象的方法  比如你定义那些 po.test什么的句素属于po的
而最后那个 $mo.test 调用出错,因为 test这个其实本身就素一个定义过的方法,你在那里调用的访问权限不对,对于访问权限有private、protected、public
class A
  def o
    p :o
  end
  protected:o
end
a = A.new
a.o

至于数组那个列子,先复制到脚本里,运行工程,然后按F12重新运行,就会出现你说的那个堆栈错误的。。=v=

作者: simounF    时间: 2006-12-20 20:18
提示: 作者被禁止或删除 内容自动屏蔽
作者: Benavii    时间: 2006-12-21 07:48
大家都问很高深的问题{/gg}我问个白点的……正则表达式是什么{/gg}

看了F1的解释,仍然不理解orz

还有,哈希表和普通数组有什么区别{/gg}
作者: link006007    时间: 2006-12-21 09:03
以前问过的一个问题,现在忽然又想起来还没有解决...

就是关于 ruby 数组的 结构.

在 Ruby 的数组中, 是不要预定空间长度的, 而且是可以动态的扩展的. 这个和 C 中的数组
在性质上已经不一样了. 应该更像是向量或者链表这种数据结构,但又根本不是,
因为, 在内部数据的类型上, 似乎可以不受数组内的数据必须是同一类型的数据的限制(弱类型的优势?), 即使是链表, 也要有指向特定数据类型的指针吧?


所以我对它的结构很感兴趣, 它是怎样实现的?
(不知道为什么,我载下来时运行就一直报错, 后来给我删的面目全非, 现在当当看Array.c 看不出什么明堂来 ... 缺失东西太多了... 我果然是万年小白{/ll})

贪心的某人爬走 ...  ...

作者: 柳柳    时间: 2006-12-21 09:27
for actor in $game_party.actors
  yield actor
end
小夏,这个如果不用yield来写,应该是什么样子呢?此外这个东西:

$game_temp.message_proc = Proc.new { @message_waiting = false }
是做什么用的?

$game_system.magic_number = $data_system.magic_number
这个东西是什么用处?
作者: 六脉神剑    时间: 2006-12-21 16:45
一个遗留了很久的问题:
Interpreter 7的最后定义事件中脚本的解释器里,有这么个东西:
    # 返回值为 false 的情况下
    if result == false
      # 结束
      return false
    end
    # 继续
    return true


这样当在事件第一行的脚本中写xx = false的时候,result返回了false,接着这个方法也跟着返回,于是进入了无限恶性循环。
这里不知道为什么要做这个判断。尝试把这里改为返回永真,之后也没有发现运行不正常。
作者: 雷欧纳德    时间: 2006-12-21 21:15
以下引用Benavii于2006-12-20 23:48:00的发言:

大家都问很高深的问题我问个白点的……正则表达式是什么

看了F1的解释,仍然不理解orz

还有,哈希表和普通数组有什么区别

关于正则表达式:
1、首先正则表达式只是用于操作字符串的,也就是对字符串的匹配操作;
2、要明确关于正则表达式的字面值,可以用//来定义,当然,它是属于Regexp类的对象,可以使用Regexp类里的match(aString)、=~之类的方法;
3、关于匹配的规则:其实F1里把规则的说的很清楚的,偶在这就来Window_Message里的一个简单的来说说吧。
例:text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
   .1 对于gsub!这个方法当然是在String里定义的,是操作字符串的,这里就不过多解释,具体讲下后面()里的内容;
   .2 //之间的内容就素正则表达式的字面值,中间的一连串的匹配关系,\\匹配'\'这个符号本身,两条\线是因为有一条是转义的,比如\"这个;接下来是[Cc],[]并不是匹配中括号本身,而这个在F1里说过的,是进行选择匹配,也就是,只要这里是C或者是c都可以;再继续是
\[([0-9]+)\]这一串,\[是经过\号转义的匹配左中括号,继续是中间小括号里的内容这个()并不是要匹配的内容,而是一个后向引用,呃 `` 这又素啥,就是把这个括号里匹配到的部分记录在$1这个变量中,当然对应的第二个括号里匹配到的内容就放在$2里,[0-9]和[Cc]相同,只要是0-9之间的数字都可以匹配,后面一个+号,是匹配的个数,也就是说可以是0-9中的一个或者多个,比如5或者65或者253等都行。最后是\],也就是右中括号。汗,这么乱,那来整理下需要匹配的顺序:
1.\\ ; 2.C或者c都可 ; 3.[号 ; 4.0-9中的数字1个或者多个,并把他记录到$1里 ; 5. ]号
那么,下面这些就是可以的 \\c[7] 、\\C[12] 、\\c[0] 等
下面的是不符合要求的  \\cc[5]、\\[5]等
好了,正则表达式大概就介绍这么,至于其中的许多方法可以参考正则表达式的类。


关于数组和hash:
要说区别,其实在ruby唯一的区别就是 取值的主键不同,数组通过整数取值,hash可以用任何键值进行取值,其他的array和hash就没区别了。


先闪去上课。。。呃 。。。
作者: 雷欧纳德    时间: 2006-12-21 21:28
以下引用link006007于2006-12-21 1:03:12的发言:

以前问过的一个问题,现在忽然又想起来还没有解决...

就是关于 ruby 数组的 结构.

在 Ruby 的数组中, 是不要预定空间长度的, 而且是可以动态的扩展的. 这个和 C 中的数组
在性质上已经不一样了. 应该更像是向量或者链表这种数据结构,但又根本不是,
因为, 在内部数据的类型上, 似乎可以不受数组内的数据必须是同一类型的数据的限制(弱类型的优势?), 即使是链表, 也要有指向特定数据类型的指针吧?


所以我对它的结构很感兴趣, 它是怎样实现的?
(不知道为什么,我载下来时运行就一直报错, 后来给我删的面目全非, 现在当当看Array.c 看不出什么明堂来 ... 缺失东西太多了... 我果然是万年小白)

贪心的某人爬走 ...  ...



[本贴由作者于 2006-12-21 1:23:05 最后编辑]



呃 `` 这个  

1、ruby是完全对象,java都不是完全对象,最明显的java的1、2、3之类的不是对象,而在ruby中则是;
2、ruby数组中保存的对象的引用集合,可以通过这个引用索引到该对象;
3、其实数组和hash是相同的,只是hash保存的是主键和键值的引用。

呃 ``` 偶理解到此,要问在c语言中怎么扩充的array,偶也米看。。。- -b
作者: 雷欧纳德    时间: 2006-12-22 00:08
以下引用柳柳于2006-12-21 1:27:25的发言:

for actor in $game_party.actors
yield actor
end
小夏,这个如果不用yield来写,应该是什么样子呢?此外这个东西:

$game_temp.message_proc = Proc.new { @message_waiting = false }
是做什么用的?

$game_system.magic_number = $data_system.magic_number
这个东西是什么用处?

1、yield
def orz
  for actor in $game_party.actors
    yield actor
  end
end

orz{|actor| p actor.name}

这个和

for actor in $game_party.actors
  p actor.name
end

有区别么... - -b
显然后面那个更方便..-v-

所以yield一般用在实现回调的地方...

2、Proc
这是过程对象的类,用于创建过程对象
$game_temp.message_proc = Proc.new { @message_waiting = false }
后面带了一个块,当然那个块不会被执行,和yield那里一样,只要在调用了call方法之后才执行块里的内容,也就是在对话完毕后调用$game_temp.message_proc.call,所以
@message_waiting = false了,可以用于在其他地方改变内部变量呢,当然块也可以带参数的
a = Proc.new{|orz| p orz}
a.call("orz") ... - -b

3、$game_system.magic_number = $data_system.magic_number这个东西在游戏完成后发布了就米用了的,只是还在制作的时候才会有作用,工程只要被进行修改之后$data_system.magic_number的值就会被改变,所以,主要是用于在制作过程中调式的时候比如修改了主角初始位置坐标或者地图什么的就会重新加载地图。。。- -b

作者: 雷欧纳德    时间: 2006-12-22 00:17
以下引用六脉神剑于2006-12-21 8:45:00的发言:

一个遗留了很久的问题:
Interpreter 7的最后定义事件中脚本的解释器里,有这么个东西:

   # 返回值为 false 的情况下
   if result == false
     # 结束
     return false
   end
   # 继续
   return true


这样当在事件第一行的脚本中写xx = false的时候,result返回了false,接着这个方法也跟着返回,于是进入了无限恶性循环。
这里不知道为什么要做这个判断。尝试把这里改为返回永真,之后也没有发现运行不正常。


恩、其实改为永真也没什么不正常,那个只影响到推进索引@index而已,不推进就不会继续执行,其实改为永真还更好,因为有时候有的人在事件中写脚本的时候,比如关闭开关1号
$game_switches[1] = false ,这样就出现问题了,程序会卡住,但他怎么也看不出原因在哪,又没有死循环什么的,所以需要注意下这个问题。

作者: 美兽    时间: 2006-12-22 02:30
$game_switches[1] = false ,这样就出现问题了,程序会卡住,但他怎么也看不出原因在哪,又没有死循环什么的,所以需要注意下这个问题。




话说这个问题偶遇到不素一次两次了,就是新建的变量$new_name,放在条件分歧中也常常遇到这个问题,最后只好把布尔值改成0和1两个整数来用.......原来如此,原来如此,

话说改成真,真的没副作用吗???
作者: 雷欧纳德    时间: 2006-12-22 06:13
以下引用美兽于2006-12-21 18:30:21的发言:
话说改成真,真的没副作用吗???

偶觉得米副作用。。。- -b
作者: 柳柳    时间: 2006-12-22 06:43
    result = eval(script)
    # 返回值为 false 的情况下
    if result == false
      # 结束
      return false
    end
    # 继续
    return true

这个东西和

return eval(script)

有什么区别?……{/gg}

这个eval是怎么return的?为何第一行是=false就直接return一个false?


题外话,感觉小夏像是某种答题机一类的。
作者: 雷欧纳德    时间: 2006-12-22 07:22
以下引用柳柳于2006-12-21 22:43:32的发言:

   result = eval(script)
   # 返回值为 false 的情况下
   if result == false
     # 结束
     return false
   end
   # 继续
   return true

这个东西和

return eval(script)

有什么区别?……

这个eval是怎么return的?为何第一行是=false就直接return一个false?


其实没区别…… 就算返回nil也一样……

题外话,感觉小夏像是某种答题机一类的。

{/gg}{/gg}{/gg}
作者: 六脉神剑    时间: 2006-12-23 13:04
为何第一行是=false就直接return一个false?

我也没懂这个,小夏怎么……好像无视了这个问题 >__>
作者: 雷欧纳德    时间: 2006-12-23 15:38
以下引用六脉神剑于2006-12-23 5:04:23的发言:


为何第一行是=false就直接return一个false?

{/gg}{/gg} 关于eval的返回值?? 怎么可能第一行是false就返回false呢。。。返回的是最后一个计算式子的值的
事件脚本:false
          true
最后返回true咯。。-v-
作者: 六脉神剑    时间: 2006-12-23 19:26
只要在false那个算式上面写有任何东西(包括注释)就可以不返回false……{/gg}
# 第一行
a = false;

也就是说……难道,只要脚本中不是只有一个值为false的算式,result就不会返回false?
作者: 尤莉斯    时间: 2006-12-27 04:51
以下引用六脉神剑于2006-12-23 11:26:01的发言:

只要在false那个算式上面写有任何东西(包括注释)就可以不返回false……

# 第一行
a = false;

也就是说……难道,只要脚本中不是只有一个值为false的算式,result就不会返回false?


不是这样的吧``` {/gg}  只要脚本有最后计算的那条语句的值为false 就会返回false的,不论第一行是否有东西



作者: Benavii    时间: 2007-1-6 23:43
=v=继续问基本问题……

什么是堆栈和栈深度过深……


作者: 轮回者    时间: 2007-1-6 23:49
def test1
  test2
end
def test2
  test1
end
test1
这个?
作者: 尤莉斯    时间: 2007-1-6 23:54


ruby的数组其实就素堆栈、数组、队列、双队列等等````

堆栈过深就素出现了类似递归调用米终止 而产生内存益处 ``` -v-
作者: 轮回者    时间: 2007-1-6 23:56
真小夏(5102040) 15:50:53
呃  。。 汗 。。  8就是 内存益出而已嘛。。v-

作者: Benavii    时间: 2007-1-7 00:02
orz我没学过编程...其实只是单纯名词解释希望orz orz
作者: 神思    时间: 2007-1-10 22:33
-____-发现了这么个强悍帖.........
发现美兽殿刚好问了在下想问的问题````~~~~~

另外``引用66的话....

真的很像答题机``````````````
作者: 六脉神剑    时间: 2007-1-26 18:10
以下引用尤莉斯于2006-12-26 20:51:03的发言:


以下引用六脉神剑于2006-12-23 11:26:01的发言:

只要在false那个算式上面写有任何东西(包括注释)就可以不返回false……

# 第一行
a = false;

也就是说……难道,只要脚本中不是只有一个值为false的算式,result就不会返回false?



不是这样的吧```   只要脚本有最后计算的那条语句的值为false 就会返回false的,不论第一行是否有东西

一试便知……{/pz}




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