前两天想为一个Swing的程序嵌入一个动态语言,用来编写自动化测试的脚本。因为觉得现在Ruby挺火的就选了JRuby了。结果发现JRuby好像不支持中文。比如下面这段代码在Eclipse+JDK1.5的环境下运行,控制台输出的结果是一个“灎”
不得以,只能找来JRuby的源码调试了一下,最后发现方法
org.jruby.lexer.yacc.StringTerm.parseStringIntoBuffer可能有点问题。这个方法在解析Ruby代码时候好像没有考虑多字节语言,把一个char直接转型成了byte。“增”字的Unicode编码是0x589E,“加”的Unicode编码是0x52A0,转换成byte后,前者成了0x9E,后者成了0xA0,0x9EA0刚好是GBK编码的"灎"字。而我的Eclisp控制台的默认编码方式就是GBK.
后来我把上面提到的方法parseStringIntoBuffer试着稍微改了一下,大概思路就是,如果是一个多字节的char,就转换成一个byte数组,而不是直接转型成byte.
然后上面例子就通过了。 不过没有在其他的环境(不同的语种)下测试过。
package nc.ui.script;
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
public class Unicodetest {
public static void main(String[] args) throws BSFException {
BSFManager.registerScriptingEngine("ruby", "org.jruby.javasupport.bsf.JRubyEngine", new String[] {"rb"});
BSFManager manager = new BSFManager();
manager.exec("ruby", "(java)", 1, 1, "puts '增加'");
//what i get in the console is 灎
}
}
不得以,只能找来JRuby的源码调试了一下,最后发现方法
org.jruby.lexer.yacc.StringTerm.parseStringIntoBuffer可能有点问题。这个方法在解析Ruby代码时候好像没有考虑多字节语言,把一个char直接转型成了byte。“增”字的Unicode编码是0x589E,“加”的Unicode编码是0x52A0,转换成byte后,前者成了0x9E,后者成了0xA0,0x9EA0刚好是GBK编码的"灎"字。而我的Eclisp控制台的默认编码方式就是GBK.
后来我把上面提到的方法parseStringIntoBuffer试着稍微改了一下,大概思路就是,如果是一个多字节的char,就转换成一个byte数组,而不是直接转型成byte.
String s = new String(new char[] {c});
byte[] bs = s.getBytes();
for (byte b : bs)
{
buffer.append(b);
}
然后上面例子就通过了。 不过没有在其他的环境(不同的语种)下测试过。