zoukankan      html  css  js  c++  java
  • 解决erlang R17无法识别中文问题

    erlang更新到R17已有一段时间了。公司项目打算从旧版的erlang迁移到R17,却不料有不少的困扰,当中一个问题是中文问题。

    这个问题非常easy重现:新建一个文件t.erl。保存为utf-8无bom格式

    -module(t).
    -export([test/0]).
    test() ->
    	["我", <<"我">>].
    在旧版的erlang中,以下的代码能正常工作。结果就是:

    Eshell V5.9.1 (abort with ^G)
    1> c(t).
    {ok,t}
    2> t:test().
    [[230,136,145],<<230,136,145>>]
    R17编译后的执行结果为:

    Eshell V6.0 (abort with ^G)
    1> c(t).
    {ok,t} 
    2> t:test(). 
    [[25105],<<17>>]
    找到erlang的文档,erlang更新到R17后,默认编码从Latin-1换成了utf8

    In Erlang/OTP 17.0, the encoding default for Erlang source files was switched to UTF-8 and in Erlang/OTP 18.0 Erlang will support atoms in the full Unicode range, meaning full Unicode function and module names

    想让R17正确识别utf-8无bom格式的代码文件。方法就是在文件头部加上“%% coding: latin-1”,代码就变成这样:

    %% coding: latin-1
    -module(t).
    -export([test/0]).
    test() ->
          ["我", <<"我">>].
    问题是,写个脚本对旧的代码文件做改动尽管不麻烦。但新加进来的文件还要加上这个头部申明,确定有点坑爹。并且受影响的还有 file:consult/1 ,也是要加上头部申明

    最脑裂的是erlang没有提供启动參数,用来支持原来的latin-1模式。

    所以。这里在erlang基础上又一次实现erlang的编译,代码例如以下:

    -module(test).
    -compile(export_all).
    
    compile(FileName) ->
    	compile(FileName, [verbose,report_errors,report_warnings]).
    
    compile(FileName, Options) ->
    	Module = filename:basename(FileName),
    	{ok, Forms } = epp:parse_file(FileName, [{default_encoding, latin1}]) ,
    	{ok, Mod, Code} = compile:forms(Forms, Options),
    	{ok, Cwd} = file:get_cwd(),
    	code:load_binary(Mod, FileName, Code),
    	file:write_file(lists:concat([Cwd, Module, ".beam"]), Code, [write, binary]).
    注意了,以上代码不要在R17之前erlang使用,某些接口erlang还没提供支持。执行结果例如以下:

    14> c(test).
    {ok,test}
    15> test:compile("t.erl").
    ok
    16> t:test().
    [[230,136,145],<<230,136,145>>]
    另外。也又一次实现了file:consult/1,例如以下:

    consult(File) ->
    	case file:open(File, [read]) of
    	{ok, Fd} ->
    		R = consult_stream(Fd),
    		_ = file:close(Fd),
    		R;
    	Error ->
    		Error
    	end.
    
    consult_stream(Fd) ->
    	_ = epp:set_encoding(Fd, latin1),
    	consult_stream(Fd, 1, []).
    
    consult_stream(Fd, Line, Acc) ->
    	case io:read(Fd, '', Line) of
    	{ok,Term,EndLine} ->
    		consult_stream(Fd, EndLine, [Term|Acc]);
    	{error,Error,_Line} ->
    		{error,Error};
    	{eof,_Line} ->
    		{ok,lists:reverse(Acc)}
    	end.
    尽管这里能解决erlang R17无法识别中文问题, 但还是希望erlang在以后的版本号能提供一个參数用以兼容latin的代码。



    參考:http://blog.csdn.net/mycwq/article/details/40718281

  • 相关阅读:
    三元操作符的类型务必一致
    a++ 和 ++a 的区别
    TCP/IP四层协议模型与ISO七层模型
    CentOS 7.0 使用 yum 安装 MariaDB 与 MariaDB 的简单配置
    修改gcc/g++默认include路径
    js中Math.random()生成指定范围数值的随机数
    在 QML 中创建 C++ 导入类型的实例
    QML从文件加载组件简单示例
    Android插件化开发---执行未安装apk中的Service
    游戏开发热门技术浅析
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7278315.html
Copyright © 2011-2022 走看看