Project1

标题: 问个关于ruby的问题 [打印本页]

作者: 星之璇    时间: 2010-8-1 18:08
标题: 问个关于ruby的问题
本帖最后由 DeathKing 于 2010-8-12 08:38 编辑

就是Marshal模块中的dump和load
感觉这个读写文件的模块好强大啊~直接就把对象输出为数据了
2个问题:
1. 对同一文件的读写,dump 和 load 各对象的顺序是不是要一致?
2. 写入文件中的字符串是什么编码的?gb2312?utf8?utf16?可以改么?

接下来是扯开话题了:
VX中的鼠标脚本有么?居然没找到……
有没有办法引入输入法?

原因是这样的……想改vx中的数据结构,于是想大不了我用RGSS自己设计个数据库编辑……
作者: DeathKing    时间: 2010-8-1 18:19
紫苏为我们附上了一个很详细的讲解:http://rpg.blue/thread-139590-1-3.html
$KCODE可以修改字符集

VX中有鼠标脚本,输入法的实现也可以(已有脚本,搜索乎?)

Ruby OOP,无数据结构?
作者: 星之璇    时间: 2010-8-1 21:02
谢谢~
鼠标脚本没有搜索到
输入法实现也不能直接用PC的输入法
那$KCODE默认是哪个?

关键是改了数据结构后,RMVX除了事件和公共事件,以及一些不想改的数据,都废了,总得自己再做个编辑器吧~
作者: DeathKing    时间: 2010-8-1 23:31
回复 星之璇 的帖子


在Ruby 1.9.1中, $KCODE的默认值是nil,对于RGSS2中,可以使用p $KCODE 得知。

如果没记错的话,沉影前辈的 新菜单样式 里面就有鼠标脚本。
输入法脚本参见: 人物创建 脚本。
作者: 紫苏    时间: 2010-8-2 03:38
RGSS 默认是 UTF-8,你可以通过修改 $-K 或者 $KCODE 的值改变编码,以下几种是 Ruby 支持的编码:
# - None (n or N)
# - EUC (e or E)
# - Shift_JIS (s or S)
# - UTF-8 (u or U)
那么 $KCODE = "S" 就告诉解释器现在开始使用 Shift_JIS 字符集了。注意这个修改不但改变了字符串和正则表达式的解码,同时也会改变整个脚本的解码方式,即解释器解码并解析脚本源文件的方法

至于其它字符集,和平台有关,在 Windows 上可以使用 Windows API 控制 Windows 的代码页,主要也就是用 MultiByteToWideChars 和 WideCharsToMultiByte 这俩函数
作者: 星之璇    时间: 2010-8-2 09:53
谢谢楼上2位前辈~

还有个小问题:
怎么用ruby读文本文件?
作者: 八云紫    时间: 2010-8-2 12:22
回复 星之璇 的帖子

open 函数
   
作者: 星之璇    时间: 2010-8-3 10:43
回复 魔女真利亞 的帖子


  这个……XXX = open(file, mode)  只是读取文件的通用格式……
然后呢?怎么读字符?然后,还是老问题,怎么设定读取该文本文件的字符集?只是该文件,$KCODE把所有的字符集都改了哎
作者: 八云紫    时间: 2010-8-3 10:53
本帖最后由 魔女真利亞 于 2010-8-3 11:51 编辑

回复 星之璇 的帖子

看下 File 类说明吧。

读取后,使用 MultiByteToWideChar 转换~
   
作者: 调律    时间: 2010-8-3 11:44
求MultiByteToWideChars参数表解释……此API完全不会用= =
作者: 八云紫    时间: 2010-8-3 11:57
百度百科 http://baike.baidu.com/view/1907282.htm?fr=ala0_1
                http://baike.baidu.com/view/2083430.htm

用法的话,百度上搜索下吧,其实咱用的夜是不很熟练。

Win32API声明应该是这样的:
   Win32API.new("Kernel32.dll", "MultiByteToWideChar", %w(i l p i p i), "i");

可能是错误的。~~~{:nm_4:}
作者: 调律    时间: 2010-8-3 12:17
= =在下还是不明白call的时候应该填什么……百科上的东西完全看不懂嘛!【掀桌】
作者: 八云紫    时间: 2010-8-3 12:27
回复 调律 的帖子

http://dev.firnow.com/course/3_p ... 20071019/78104.html

具体参数只能去看百科或者是 MSDN 了,现在手头没有 MSDN ,抱歉~~~
   
作者: 灼眼的夏娜    时间: 2010-8-3 12:32
RM直接由转码的脚本 搜索下吧
作者: 小鱼子    时间: 2010-8-4 11:25
system('notepad.exe text.txt')
红色部分为文件名
读文档
顺带一个生成文件
file = File.open("Finished.exe", "wb")
Marshal.dump($game_variables, file)
file.close
红色为文件名
作者: 星之璇    时间: 2010-8-4 12:17
本帖最后由 星之璇 于 2010-8-4 12:21 编辑

回复 小鱼子 的帖子

原来都是要用API的啊~我试试吧~
   
没想到ruby读文本文件这么不给力……
作者: 八云紫    时间: 2010-8-4 12:27
回复 小鱼子 的帖子

为什么要用 notepad.exe 开进程???
   
作者: 小鱼子    时间: 2010-8-4 15:53
文本文件,为了保证即使系统关联出错也不会影响读取……
作者: 八云紫    时间: 2010-8-4 15:55
记得用 system 后 RM 会挂掉~~
作者: 小鱼子    时间: 2010-8-4 16:28
我试过了,不会
作者: 八云紫    时间: 2010-8-4 16:48
不过,很在意。

直接用 记事本 读的话,是不是和 Ruby 没关系了~~~
作者: 星之璇    时间: 2010-8-5 11:25
回复 魔女真利亞 的帖子

所以觉得这个方法很山寨……
ruby读文本这么麻烦
   
作者: 紫苏    时间: 2010-8-5 11:36
open 打开一个文件输入流,获取文件全部内容,关闭,然后根据文件的编码把字符串转码为 UTF-8 即可。你可以搜索一下“转码”,有前人写的现成代码可以复制粘贴
作者: IamI    时间: 2010-8-5 12:02
于是跑来乱入解答第一个问题:dump 1然后dump 2,load先出1再出2,可以理解成FIFO
Marshal格式请点击这里
作者: 星之璇    时间: 2010-8-7 17:02
回复 紫苏 的帖子

如何获取输入流全部内容?用哪个函数?
   
作者: 紫苏    时间: 2010-8-8 10:06
回复 星之璇 的帖子

IO#read,不传递参数则读取数据到 EOF 为止
作者: 星之璇    时间: 2010-8-8 10:24
回复 紫苏 的帖子

谢谢~

那……还是问句老话,ruby认为该文本的编码是哪个呢?
   
作者: 紫苏    时间: 2010-8-8 10:48
回复 星之璇 的帖子

Ruby 没有主见,决定文本是什么编码的是脚本编写者你。通常情况下程序进行正常的文本文件 I/O 操作,其编码都不会是动态的,所以在程序中可以静态决定编码

如果你能确定某个文本文件的编码,那么你脚本的输入过程应该是:
1、open 打开输入流
2、str = "" 初始化字符串缓冲区
3、read 将流中的字节全部读取到 str 中
4、如果文本文件编码本来就是 UTF-8,那就不用改了,可以直接使用;如果不是,通过 MultiByteToWideChar 将字符串转码为 UTF-16,然后再用 WideCharToMultiByte 把 UTF-16 的字符串转换为 UTF-8

关于自动检测编码:
如果编码是 Unicode(UTF-8、UTF-16、UTF-32 或者其它一些比较罕见的 Unicode 家族成员),那么可以在文件开头写入标识了文件属于那一种 Unicode 表示的字节序记号(BOM),这样就能在运行时决定文本文件编码,具体的码点可以参考:
http://zh.wikipedia.org/zh-cn/%E ... F%E8%A8%98%E8%99%9F
如果文件编码不一定是 Unicode,或者文件开头不一定包含 BOM,那你可以写一个专门在运行时自动检测文本文件编码格式的脚本,读取足够的数据,统计出各种编码的特征,然后根据统计结果给出最有可能的编码。这是一个非确定性的过程,而且必然会造成一定的效率损失
作者: 星之璇    时间: 2010-8-8 14:34
回复 紫苏 的帖子

在ruby 的文档里找到了这段:

a = File.new('some filename', 'rb:ASCII-8BIT') # strings from this will be read in as ASCII-8BIT
b = File.new('some filename', 'r') # strings from this will be read in as whatever the Encoding.default_external is
# you can change what the encoding will be
a.set_encoding "UTF-8" # from now on it will read in UTF-8
   
作者: 紫苏    时间: 2010-8-8 16:00
回复 星之璇 的帖子

这个是 Ruby 1.9 才有的功能,RM 用的是 Ruby 1.8,并不支持这种文件打开的模式
   
那就比如,某文本文件是utf-16的编码,我该如何读取呢? ruby下输入了个File.public_methods……瞬间晕了,没找到

如果本来就是 UTF-16,那就不需要 MultiByteToWideChar 了(已经是宽字符 Wide character),获取数据后直接 WideCharToMultiByte 转到 UTF-8:

str = ''
open("filename") { |fin|
    str = fin.read
}
WideCharToMultiByte.call(...)   # 把 str 从 UTF-16 转码到 UTF-8

在 Ruby 里类本身也是对象,是 Class 类型的对象,而 public_methods 是返回接收者对象的公有实例方法,你这里指定的接收者是 File,File 是一个 Class 对象,所以这里返回给你的是该 Class 对象,包括其基类的实例方法

我之前说的 IO#read 是 IO 类实例的实例方法,“类#方法”表示类的实例方法,而不是类本身这个 Class 对象的实例方法(也就是其它语言中的静态方法)
File 是 IO 的子类,所以也继承了 IO#read方法
你想要的是 File 类的实例方法,可以通过 instance_methods 来返回某个类的实例方法(或者已经有了一个 File 的实例对象,就可以让这个对象作为接受者调用 public_methods):File.instance_methods
当然凭人眼想要在这么一堆没有换行的方法名里浏览不是什么轻松的事,这里为了演示 read 确实是 File 的实例方法,可以尝试运行 p File.instance_methods.include?("read")

作者: 一瞬间的幻觉    时间: 2010-8-8 20:36
你们都高手,事件派的。。。路过
作者: 星之璇    时间: 2010-8-8 23:26
回复 一瞬间的幻觉 的帖子

这个……因为我想做的……事件解决不了啊……
   
作者: 星之璇    时间: 2010-8-8 23:28
回复

str = ''
open("filename") { |fin|
    str = fin.read
}
WideCharToMultiByte.call(...)   # 把 str 从 UTF-16 转码到 UTF-8

紫苏 发表于 2010-8-8 16:00


那就避免不了下一个问题了,WideCharToMultiByte还有MultiByteToWideChar两个函数的具体用法……对API不是很懂
作者: 紫苏    时间: 2010-8-9 01:31
回复 星之璇 的帖子

看脚本最后的 String#to_unicode 和 String#to_UTF8 方法
http://rpg.blue/forum.php?mod=vi ... 23477&from=home
   
作者: 小鱼子    时间: 2010-8-9 13:36
貌似中文名文件会出错……
作者: 星之璇    时间: 2010-8-9 18:47
回复 小鱼子 的帖子

这个估计是中文的编码问题……
   
作者: 星之璇    时间: 2010-8-9 18:48
回复 紫苏 的帖子

懂了~这个类挺好,收下了~
   




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