• Rails 的后端不支持转换到拼音的 transliteration,因为它用了个字典,里面根本就没有这个数据。 有一些拼音的 gem 你可以用。 ICU 没有很好的 ruby 绑定的库,但是 ICU 是能很轻易的做到这个的。(这些数据都在 CLDR 这个项目里)

  • 最近重新捡起了这个事情,花了一周的时间研究了下。写了一个验证性的实现。Unicode 正规化的效率大概能快 500% https://github.com/fantasticfears/icu4r-next 编译要依靠本地有 icu 的头。把 ICU 链接成静态库很简单,不过还没做。现在暂时写到这个地步,我好像没有动力继续下一步了...欢迎提问。

    Unicode 相关的用途和 CJK 用户应该最有关系了,日本社群实现了 CSI 后大概已经不理会处理国际化的问题了...(SHIFT_JIS 是 Unicode 史前编码,转到 UTF-8 可能有数据丢失,by Yehuda) 但是日子还是得过下去。ICU 提供的功能很多,transliterate, normalize, converter, collate, spoof_checker,Unicode 标准里提到的算法都有。twitter-cldr-rb 和 ICU 都用了 Unicode CLDR 的数据,只是 twitter-cldr-rb 用 Ruby 实现,而 ICU 是 C/C++/Java 的实现。不过我实在不想重新造轮子,所以一直想写胶水实现。

    我没想到写这个插件这么困难。MRI 内部太太太可怕了。写插件困难的地方在于 MRI 没什么文档,内部 API 随便用,毫无边界,要找到对的 API 就很麻烦了。

    然后是编码问题。MRI 的字符串一定是 byte array 加上每个字符串额外存储的编码信息。而 ICU 大部分情况下处理的是 UTF-16,所以一定要转换,为了能控制清楚编码,只好在 C 里面写。ffi 的 API 实在难以处理这种复杂的状态了。

    最后内存管理,为了转换编码写了 UChar String 的一个内部类,把 C Struct 包装到 Ruby 类(Ruby 内部有个 Data 的类,BigNumber 也用了这个)。这样既可以用来调用 ICU 的 C API,也可以靠 Ruby GC 来管理生成的内存(MRI 在 C 这个层面是扫寄存器!和栈来追踪有没有东西需要清理)。原来的 icu4r 这个库把类似功能包装出了一个真的 UString 类,用来存 Unicode 字符串,这个库的历史都在 1.9 (CSI model) 之前了。现在的 String 类功能丰富,做个内部类方便做胶水就好,放出来八成没什么用...

    附写插件比较有用的参考:

  • Discourse 1.6+ 有启动向导了,手动创建管理员也没法跳过。

    run:
      - exec: echo "Beginning of custom commands"
      ## If you want to set the 'From' email address for your first registration, uncomment and change:
      ## After getting the first signup email, re-comment the line. It only needs to run once.
      - exec: rails r "SiteSetting.has_login_hint=false"
      - exec: rails r "SiteSetting.wizard_enabled=false"
      - exec: echo "End of custom commands"
    

    在 app.yml 的 hook 里还是可以禁用相关的设置的。这和管理面板里操作的一样。

    SSO 过去的用户名也会被洗一次,有些符号或者中文会很惨...

    最后,Discourse 现在支持 SAML SSO 了。https://github.com/discourse/discourse-saml

  • 还有位置吗,有位置我也跟你们凑热闹一起住 XD @lgn21st 这个房主应该是不喜欢吵闹的...

  • Getting started with JRuby at 2016年4月17日

    我在想是不是 Gradle 这样的工具更能有效地管理依赖和启动呢?

    JRuby 的巨大优势之一也是无数的 JVM 库,这些库被打包、测试和分发到 Maven/jcenter 上。重点如果是利用这些库的话,未必 jbundler 等是一个很好的办法

  • #85楼 @geekontheway 为什么后面请求的是淘宝的 API 呢?


    回源的时候的延迟,gem 一多特别容易让 bundle 中断,部署的时候带上 --retry 加上应该会好一些。 阿里云部署 Discourse 的时候大概因此中断了 3 - 4 次,但是问题很奇怪,有的时候是 gem 下载问题(看起来像回源失败),但是之后再执行 gem update bundler 也因为下不到 spec4.8 失败了(这肯定就不是回源的问题了)。倒是 DigitalOcean 都只中断了 1 次,谜一般...😓

    因为不断失败,所以开始走查问题。以下尝试来自于阿里云上海的 139.196.41.197(ipip.net)机器按照 https://gems.ruby-china.org 这个 URL 部署 Discourse 碰到的错误(生产环境部署)。

    例子:

    第 2 次重试失败(FetcherError 和 GemspecError,应该是 CDN 回源的问题):

    Bundler::GemspecError: Could not read gem at /var/www/discourse/vendor/bundle/ruby/2.0.0/cache/redis-3.2.1.gem. It may be corrupted.
    Bundler::GemspecError: Could not read gem at /var/www/discourse/vendor/bundle/ruby/2.0.0/cache/msgpack-0.5.11.gem. It may be corrupted.
    Gem::RemoteFetcher::FetchError: bad response Bad Gateway 502 (https://gems.ruby-china.org/gems/rb-fsevent-0.9.4.gem)
    

    第 3 次重试失败(API 失败,SSL 签名错误;但是之前的 24 次请求没有问题):

    could not fetch from the dependency API, trying the full index
    HTTP GET https://gems.ruby-china.org/quick/Marshal.4.8/actionmailer-4.1.10.gemspec.rz
    Could not verify the SSL certificate for
    https://gems.ruby-china.org/quick/Marshal.4.8/actionmailer-4.1.10.gemspec.rz.
    

    第 4、5 次重试失败:

    ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
        server did not return a valid file (https://gems.ruby-china.org/specs.4.8.gz
        bad response Bad Gateway 502 (https://gems.ruby-china.org/specs.4.8.gz)
    

    既然不是回源问题,那么重新回到 CA 证书这个点上。按照 issues 给的链接从 https://curl.haxx.se/ca/cacert.pem 导入证书链,再指定环境变量。(缺点显而易见,公钥的 integrity 没有保障。不过这是目前的一个让源能用起来的 hack)

    然而重新回到了 4、5 次重试的时候失败的问题。虽然仍然不排除阿里云的链接问题。但结合其他人碰到的问题回到镜像的部署问题,还是应该探索下解决的办法,故已提交 issue

    http 的环境下 bundle 是成功的,不过 Discourse 相关 gem 花了 18 分钟。

  • 打算大概先自己测试一下看看坑,然后把 Discourse 的淘宝源改到 Ruby China 源。

  • rack-mini-profiler 的用途是能直接找到线上的页面的相关性能信息,但是其中也有很多服务器内部的一些安全信息,比如说 session 和 cookies 等。在 ?pp=help 中的内存相关的分析,基本上会暴露 Rack session。

    这些信息对开发者还是足够安全的。

    再加装 flamegraph 后更可以直接可视化分析热点。

  • #3楼 @luikore Ruby 这个 binding 其实也是很麻烦的。大部分的功能,用 C 再对接,写法及其特别的啰嗦。UChar 这个地方如果用 C 写,那么 FFI 就不可能再用了。OS X 这些系统没有 ICU 的头文件,所以起码还得解决各种头文件和版本的问题...

    FFI 没大问题的应该... 不过写 C-ext 执行更快一点, 而且 FFI gem 本来就是个 C-ext

    我找过几个 benchmark,ffi-icu 的速度相当没有问题,这也是我比较想继续用 FFI 的原因。

    实现一个 UChar byte array 作为 ICU 和 Ruby String 的 adapter,简单的实现考虑到复制也并不会很快... ICU 这还有很多自动的类,还做了 cow 的,比如 UnicodeString。这些都没有 extern 给 C,所以 Ruby 的话写 C extension 也不能用...

    另外的选择像 Rice 还是不够成熟,原来踩过坑吃过苦头。

  • FFI 没大问题的应该... 不过写 C-ext 执行更快一点, 而且 FFI gem 本来就是个 C-ext

    速度上确实如此。FFI 的包装主要在于方便,大部分关于 ICU 的操作只有几个函数调用罢了。除了字符串这部分,看起来是 FFI 最节省时间。而且不用像 icu4r 那样写 n * 1000 规模的 C...

    ICU 在日常使用中,系统有的概率不低,这也是用 FFI 的一个优点吧,不用下一个很大的库,也不用再编译了。

    从 UChar* 生成 Ruby 字符串, 可以直接调 Ruby 的 CAPI rb_str_new(uchar_pointer, uchar_length * 2)

    然后在 Ruby 中 str.force_encoding('utf-16le').encode('utf-8')

    UChar 可能是 malformed 的 UTF-16,所以这部分还可能出错,当然作为 gem 内部使用基本不会遇到。但是大小端序这样写似乎是大问题啊...容易碰到跨指令集的问题

    最后我有个不情之请,我实在看不懂 Haskell,你知道 Data.Text.ICU 大致是什么做法么?