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

Project1

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

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

  [复制链接]

Lv3.寻梦者

孤独守望

梦石
0
星屑
3121
在线时间
1534 小时
注册时间
2006-10-16
帖子
4321

开拓者贵宾

54
发表于 2010-10-31 21:16:05 | 只看该作者
今天没人?
Table数据的取值范围是-32767--32768。

点评

我湿了。。。至今还没动过Table  发表于 2010-10-31 22:46
简洁有力 = =b  发表于 2010-10-31 21:54
菩提本非树,明镜本非台。回头自望路漫漫。不求姻缘,但求再见。
本来无一物,何处惹尘埃。风打浪吹雨不来。荒庭遍野,扶摇难接。
不知道多久更新一次的博客
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv1.梦旅人 (禁止发言)

梦石
0
星屑
46
在线时间
10 小时
注册时间
2007-5-27
帖子
2558

第1届Title华丽大赛新人奖

53
发表于 2010-10-30 19:56:18 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
签名被屏蔽
回复 支持 反对

使用道具 举报

Lv2.观梦者 (管理员)

八云紫的式神

梦石
0
星屑
539
在线时间
1238 小时
注册时间
2008-1-1
帖子
4282

烫烫烫

52
发表于 2010-10-29 15:37:51 | 只看该作者

条件编译

原文:http://rpg.blue/thread-159531-1-2.html

对于一些不是很“动态”的条件分歧,例如对系统的判断等程序开始运行之后一般不会变的
if system_is_windows?
  def do
    #do_in_windows
  end
elsif system_is_linux?
  def do
    #do_in_linux
  end
end

由于ruby的一切都是运行时处理,而没有原生的预编译指令,所以这看起来不像预编译
但是想象一下RM的脚本架构(其他比较大的ruby工程也是像这样),在main之前,定义所有类和方法,这个过程可以近似的认为是编译
如果是做通用库,或者是需要大量执行的方法,效率会有一定提升(吗)

点评

本来我是想和 define? 一起用来解决一些纠结的事的。。。。  发表于 2010-10-29 17:05
rm for linux(wine)制作中,期待夏娜SAMA能实现到webrm上
回复 支持 反对

使用道具 举报

Lv2.观梦者 (管理员)

八云紫的式神

梦石
0
星屑
539
在线时间
1238 小时
注册时间
2008-1-1
帖子
4282

烫烫烫

51
发表于 2010-10-25 16:04:27 | 只看该作者
又自己抓出来一个ruby1.9小细节
p [1,2,3].to_s #=> "[1,2,3]"  in 1.9
p [1,2,3].to_s #=> "123"  in 1.8

数组的.to_s变成了以人类可读形式输出
rm for linux(wine)制作中,期待夏娜SAMA能实现到webrm上
回复 支持 反对

使用道具 举报

Lv3.寻梦者

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

贵宾

50
 楼主| 发表于 2010-10-24 08:12:48 | 只看该作者
本帖最后由 DeathKing 于 2010-10-24 12:23 编辑

欢欢乐乐来循环

经典的for语句:
  1. for i in 0..100
  2.   p "i count #{i}"
  3. end
复制代码
换个马甲如何?
  1. (0..100).each do |i|
  2.   p "i count #{i}"
  3. end
复制代码
原来是重复101次!
  1. 101.times do |i|
  2.   p "i count #{i}"
  3. end
复制代码
想想,是从0数到100:
  1. 0.upto(100) do |i|
  2.   p "i count #{i}"
  3. end
复制代码
我愿意倒着数:
  1. 100.downto(0) do |i|
  2.   p "i count #{i}"
  3. end
复制代码
还没数到100就别停下来
  1. i = 0
  2. while i <= 100
  3.   p "i count #{i}"
  4.   i += 1
  5. end
复制代码
似乎这个更清晰:
  1. i = 0
  2. until i == 101
  3.   p "i count #{i}"
  4.   i += 1
  5. end
复制代码
他们都是循环的快速通道:
for, while, until

Range#each
Integer#times
Integer#upto
Integer#downto
String#upto
String#downto

点评

死循环啊——比如这个RGSS文件【Ruby也可以完成,只不过比较麻烦】 Game.exe exit 多好啊~  发表于 2010-11-9 19:22
moy
goto是在太坏了...  发表于 2010-10-25 08:19
某個integer寫錯了O O  发表于 2010-10-24 12:08
让我们欢乐的goto吧囧  发表于 2010-10-24 09:50
其实还有0.step(100) {|i| p "i count#{i}"} ,顺便那个until里的=应该是==……  发表于 2010-10-24 09:06

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

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
49
发表于 2010-10-23 16:01:11 | 只看该作者
辨析:Kernel#eval、BasicObject#instance_eval、Module#module_eval(Module#class_eval)

(Kernel#)eval把给定的字符串作为代码运算并返回结果。和其它两个不同的是,eval不能传递块。binding可以作为eval的第二个参数传入。

  1. def a
  2.   b = 5
  3.   return binding
  4. end
  5. eval("p b",a) #=>"5"
复制代码
(Basic)Object#instance_eval在一个实例的上下文中eval字符串或块(可以访问类内的方法、变量等)。所有对类的方法或变量的操作只在这个实例中生效,而不会影响类的其它实例。

  1. a = String.new
  2. b = String.new
  3. a.instance_eval{
  4. def foo
  5.   p "foo"
  6. end
  7. }
  8. a.foo                         #=>"foo"
  9. b.foo rescue p nil            #=>nil
  10. p String.method_defined? :foo #=>false
复制代码
Module#module_eval(class_eval)实在模块或类的上下文中eval字符串或块。定义的东西会影响所有实例,主要用于给类或模块定义新的方法。
  1. a = String.new
  2. b = String.new
  3. String.class_eval{
  4. def bar
  5.   p "bar"
  6. end
  7. }
  8. a.bar                         #=>"bar"
  9. b.bar                         #=>"bar"
  10. p String.method_defined? :bar #=>true
复制代码
From mortal hope immortal power springs.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
48
发表于 2010-10-22 18:09:39 | 只看该作者
本帖最后由 小幽的马甲 于 2010-10-22 22:39 编辑

用一段简单的代码概括Ruby异常类要点

  1. class Test
  2.   def initialize
  3.     err = nil
  4.     begin
  5.       return unless err.nil?
  6.       raise ArgumentError, "Test"
  7.     rescue IOError
  8.       print "IOError"
  9.     rescue StandardError,ScriptError => err
  10.       print "Error:#{$!}"
  11.       retry
  12.     rescue ArgumentError
  13.       print "ArgumenError"
  14.     rescue
  15.       print "Error"
  16.     else
  17.       print "No Errors!"
  18.     ensure
  19.       print "err = #{err}\n$! = #{$!}"
  20.     end
  21.   end
  22. end
  23. Test.new
复制代码
输出:

  1. Error:Test
  2. err = Test
  3. $! =
复制代码
异常这一块难度不大,知识点不少,所以用这一段概括大部分知识点,没有接触过异常的同学看后也能明白了吧…?
From mortal hope immortal power springs.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
47
发表于 2010-10-21 20:50:00 | 只看该作者
几个神奇的位运算应用,问题转自Matrix67-Blog,代码已翻译为Ruby,限于篇幅不转代码的说明了,原文里有(其实用纸和笔画一画很容易想通{:nm_6:} )

二进制中的1有奇数个还是偶数个
我们可以用下面的代码来计算一个32位整数的二进制中1的个数的奇偶性,当输入数据的二进制表示里有偶数个数字1时程序输出0,有奇数个则输出1。例如,1314520的二进制101000000111011011000中有9个1,则x=1314520时程序输出1。
  1. def calc1(x)
  2.   5.times{|i| x ^= x >> (1 << i)}
  3.   return x & 1
  4. end
复制代码
计算二进制中的1的个数
同样假设x是一个32位整数。经过下面五次赋值后,x的值就是原数的二进制表示中数字1的个数。比如,初始时x为1314520,那么最后x就变成了9,它表示1314520的二进制中有9个1。

  1. def calc2(x)
  2.   x = (x & 0x55555555) + (x >> 1 & 0x55555555)
  3.   x = (x & 0x33333333) + (x >> 2 & 0x33333333)
  4.   x = (x & 0x0F0F0F0F) + (x >> 4 & 0x0F0F0F0F)
  5.   x = (x & 0x00FF00FF) + (x >> 8 & 0x00FF00FF)
  6.   x = (x & 0x0000FFFF) + (x >> 16 & 0x0000FFFF)
  7.   return x
  8. end
复制代码
只用位运算来取绝对值
x仍为一个32位整数。

  1. def calc3(x)
  2.   return (x ^ (~ (x >> 31) + 1)) + (x >> 31)
  3. end
复制代码
二进制逆序
    下面的程序读入一个32位整数并输出它的二进制倒序后所表示的数。
    输入: 1314520    (二进制为00000000000101000000111011011000)
    输出: 460335104  (二进制为00011011011100000010100000000000)

  1. def calc4(x)
  2.   x = (x & 0x55555555) <<  1 | (x & 0xAAAAAAAA) >>  1;
  3.   x = (x & 0x33333333) <<  2 | (x & 0xCCCCCCCC) >>  2;
  4.   x = (x & 0x0F0F0F0F) <<  4 | (x & 0xF0F0F0F0) >>  4;
  5.   x = (x & 0x00FF00FF) <<  8 | (x & 0xFF00FF00) >>  8;
  6.   x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16;
  7.   return x
  8. end
复制代码

点评

我有種感覺在RM中用binary計算不比integer快  发表于 2010-10-24 12:08
不得不佩服写出来的那个老外,神乎其技  发表于 2010-10-22 10:35
From mortal hope immortal power springs.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
46
发表于 2010-10-20 19:04:53 | 只看该作者
本帖最后由 小幽的马甲 于 2010-10-20 20:21 编辑

基本位运算
在Matrix67Blog看到Pascal版本,觉得很好,于是转为Ruby语言版

顺便说句,Ruby和Pascal的位运算优先级是不同的(和C++大致相同不过似乎也有点小区别),Ruby运算优先级参考本帖29楼

点评

>紫苏 疏忽了……已更正,感谢指出= = 位运算确实有很多巧妙的思路,令人感到非常优美,下次有机会再贴出>  发表于 2010-10-20 20:25
最后三个很有意思,学到了 ^^ 不由念及前年看过的一个 O(1) 取 1 个数的算法,其位的运用真个是鬼斧神工,叹为观止  发表于 2010-10-20 20:14
最后一位变成 0 另一种方式: x & ~1  发表于 2010-10-20 20:01
在最后加一个 1 还是写成 x << 1 | 1 较好,+ 1 一来是有优先级问题,二来效率不及位运算……不过最后还是要看编译器/解释器的优化性能了  发表于 2010-10-20 19:59
From mortal hope immortal power springs.
回复 支持 反对

使用道具 举报

Lv1.梦旅人

万物创造者

梦石
0
星屑
54
在线时间
352 小时
注册时间
2008-2-15
帖子
2432
45
发表于 2010-10-19 21:27:34 | 只看该作者
本帖最后由 小幽的马甲 于 2010-10-19 22:09 编辑

简单地说下Symbol类。
Symbol类似一个静态的String。类似于:aaa之类的字面值都是Symbol,可以调用String#to_sym或String#intern把不包含空字符的字符串转化为符号,调用Symbol#to_s或Symbol#id2name把符号转化为字符串。
作为字面值使用时,冒号后面跟双引号和单引号结果是不同的,要注意

  1. a = "abc"
  2. p :"#{a}" #=> :abc
  3. p :'#{a}' #=> :'#{a}'
复制代码
Symbol同样也有%号表示法:%s。

  1. p %s{aaa}         #=>:aaa
  2. p %s{aaa bbb}     #=>:"aaa bbb"
  3. p %s{aaa\n}       #=>:"aaa\\n"
复制代码
Symbol类有一个类方法:Symbol.all_symbols,用于以数组的形式返回所有已定义的符号对象。

Symbol一个很重要的性质是,字面值一样的Symbol都是同一个Object

  1. str1 = "aaa"
  2. str2 = "aaa"
  3. p str1.equal? str2   #=>false
  4. sym1 = :aaa
  5. sym2 = :aaa
  6. p sym1.equal? sym2   #=>true
复制代码
这使得它在执行比较的时候比String效率高(Symbol继承了Object的self==other,String则是重新定义,让两个字符串逐字比较),所以当String仅仅用来作为一个标志的时候可以考虑替换为Symbol。

  1. def move(direction)
  2.   @x += 1 if direction == :right
  3.   @x -= 1 if direction == :left
  4.   @y += 1 if direction == :up
  5.   @y -= 1 if direction == :down
  6. end
复制代码
(Ruby1.9相关)
在Ruby1.9里,Hash可以这么定义:
  1. {a:"aaa",b:"bbb"}
复制代码
它等价于
  1. {:a => "aaa", :b => "bbb"}
复制代码
在Ruby1.9中,Symbol类加入了大量的实例方法,大部分都是String类的实例方法,如capitalize、downcase、encoding
  1. p :aaa.upcase  #=>:AAA
复制代码
25楼的67在说明&的应用时给Symbol定义了to_proc方法,在Ruby1.9就不用这样,Symbol自带to_proc
  1. words = %w(hello kitty not world)
  2. list = words.map(&:capitalize)
复制代码
ok,得到了第一个字母大写的字符串数组了

顺便说一句,默认RGSS看似没怎么用Symbol,但你不知不觉地已经用了很多了。
  1.   attr_accessor :next_scene               # 切换待机中的画面 (文字列)
复制代码

点评

嗯,其实 1.9 介绍符号键 Hash 语法的目的就是为了鼓励使用符号,符号常量池的机制是牺牲了创建时间,换来空间和比较时间  发表于 2010-10-20 10:05
From mortal hope immortal power springs.
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-19 17:17

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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