<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>lululau</title>
    <link>https://ruby-china.org/lululau</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Enumerable#each (with no block given) 和 Enumerable#map (with no block given) 有什么区别</title>
      <description>&lt;p&gt;&lt;code&gt;Enumerable&lt;/code&gt; 定义的很多方法，在调用时，如果没有传递一个 block，那么这些方法都会返回一个 &lt;code&gt;Enumerator&lt;/code&gt; 实例，比如：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;each&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;map&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;select&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;each_slice&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;each_with_index&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;等等……&lt;/p&gt;

&lt;p&gt;其中的 &lt;code&gt;each&lt;/code&gt;，&lt;code&gt;map&lt;/code&gt;，&lt;code&gt;select&lt;/code&gt; 等方法所返回的 &lt;code&gt;Enumerator&lt;/code&gt; 在对其进行迭代时，都是原封不动得依次返回原 &lt;code&gt;Enumerable&lt;/code&gt; 对象的各元素。那么问题就是，这三个方法所返回的 &lt;code&gt;Enumerator&lt;/code&gt; 对象有什么区别？如果没区别的话，像 &lt;code&gt;map&lt;/code&gt;，&lt;code&gt;select&lt;/code&gt; 等会返回 &lt;code&gt;Enumerator&lt;/code&gt; 这样的设计是出于什么原因或目的？&lt;/p&gt;</description>
      <author>lululau</author>
      <pubDate>Fri, 12 Jun 2015 11:14:49 +0800</pubDate>
      <link>https://ruby-china.org/topics/25993</link>
      <guid>https://ruby-china.org/topics/25993</guid>
    </item>
    <item>
      <title>看到 String#[] 方法的一个用法</title>
      <description>&lt;p&gt;例如：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hello world"&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以用下面这量行代码代替：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;另外：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/(\w+)\s(\w+)/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;可以换成：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;/(\w+)\s(\w+)/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个不知道是不是太 out 了？&lt;/p&gt;</description>
      <author>lululau</author>
      <pubDate>Thu, 23 Jan 2014 00:50:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/16935</link>
      <guid>https://ruby-china.org/topics/16935</guid>
    </item>
    <item>
      <title>Ruby 1.9+ 的字符编码</title>
      <description>&lt;p&gt;从 1.9 开始，Ruby 增加了对字符编码的支持。这篇文章基本上是看了 Ruby 2.0 镐头书第 17 章 &lt;code&gt;Character Encoding&lt;/code&gt; 做的笔记，并补充了一些自己通过实验得到的结论。&lt;/p&gt;
&lt;h2 id="Ruby 代码文件的编码"&gt;Ruby 代码文件的编码&lt;/h2&gt;
&lt;p&gt;你需要告诉 Ruby 你的 Ruby 代码文件使用的是什么编码，因为 Ruby 中的字符串字面量、Symbol 字面量以及正则表达式字面量的字符编码在多数时候取决于定义他们的源文件的字符编码。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(1). 如果你没有声明代码文件的字符编码，那么 Ruby 源文件的默认编码是这样确定的：&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 1.9 默认 Ruby 源文件的编码为 &lt;code&gt;US-ASCII&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;default_source_encoding.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;__ENCODING__&lt;/span&gt;   &lt;span class="c1"&gt;# 通过 __ENCODING__ 来查询当前文件的字符编码&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 1.9 
ruby default_source_encoding.rb
&lt;span class="c"&gt;# 输出：&lt;/span&gt;
US-ASCII
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 2.0 默认 Ruby 源文件的编码为 &lt;code&gt;UTF-8&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby default_source_encoding.rb
&lt;span class="c"&gt;# 输出：&lt;/span&gt;
UTF-8
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;(2). 指定 Ruby 源文件的字符编码&lt;/strong&gt;
    在 Ruby 1.9 中，如果代码文件中包含了非 ASCII 字符，或者在 Ruby 2.0 中代码文件中包含了非 UTF-8 字符，那么就需要在代码文件中声明该代码文件的字符编码：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;non_ascii.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'中文'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 1.9
ruby non_ascii.rb
&lt;span class="c"&gt;# 输出：&lt;/span&gt;
non_ascii.rb:2: invalid multibyte char &lt;span class="o"&gt;(&lt;/span&gt;US-ASCII&lt;span class="o"&gt;)&lt;/span&gt;
non_ascii.rb:2: invalid multibyte char &lt;span class="o"&gt;(&lt;/span&gt;US-ASCII&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ruby 使用一个看似神奇实则很简单的标记规则来指定代码文件的字符编码：如果一个文件的第一行（如果第一行是 UNIX shebang &lt;code&gt;#!&lt;/code&gt;，那么就是第二行）是注释行，Ruby 会使用 &lt;code&gt;coding:\s*(\S+)&lt;/code&gt; 这个正则表达式来对这个注释行进行匹配，如果匹配成功那么该文件的字符编码就被设置为 &lt;code&gt;$1&lt;/code&gt;的值。所以，可以这样将一个 Ruby 代码文件的字符编码设置为 UTF-8：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为 Ruby 只是检索字符串中是否包含 &lt;code&gt;coding:&lt;/code&gt; 这个子字符串，所以实际上也可以这样写：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# encoding: utf-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Emacs 用户可能会更喜欢这样写：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# -*- encoding: utf-8 -*-&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;另外，如果 Ruby 代码文件包含了 UTF-8 BOM，也就是说代码文件的头三个字节是 &lt;code&gt;\xEF\xBB\xBF&lt;/code&gt;，那么 Ruby 认为这个代码文件的字符编码是 UTF-8，而不管上述的标记行：  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;gbk.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: GBK&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;__ENCODING__&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby gbk.rb
&lt;span class="c"&gt;# 输出:&lt;/span&gt;
GBK
ruby &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'print [0xEF, 0xBB, 0xBF].pack("c*")'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; bom.rb
&lt;span class="nb"&gt;cat &lt;/span&gt;gbk.rb &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; bom.rb
ruby bom.rb
&lt;span class="c"&gt;# 输出：&lt;/span&gt;
UTF-8
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;(3).  查询代码文件的编码：&lt;/strong&gt;&lt;br&gt;
     特殊常量 __ENCODING__ 存储了文件的字符编码&lt;/p&gt;
&lt;h2 id="字符串（还有Symbol和Regexp）字面量的字符编码"&gt;字符串（还有 Symbol 和 Regexp）字面量的字符编码&lt;/h2&gt;
&lt;p&gt;在 Ruby 1.9+ 中，每一个字符串对象、Symbol 对象和正则表达式对象都有自己的字符编码。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;show_encoding.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"中文"&lt;/span&gt;
&lt;span class="n"&gt;sym&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;
&lt;span class="n"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Regexp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"GBK"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby show_encoding.rb
&lt;span class="c"&gt;# 输出：&lt;/span&gt;
UTF-8
US-ASCII
GBK
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;字符串对象、Symbol 对象和正则表达式对象的字面量的编码是这样确定的：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(1). 字符串字面量总是以定义它的源代码文件的字符编码来编码的。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;utf8.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: utf-8&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"中文"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;gbk.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: GBK&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"中文"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby utf8.rb
ruby gbk.rb
&lt;span class="c"&gt;# 输出:&lt;/span&gt;
UTF-8
UTF-8
GBK
GBK
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;(2). Symbol 和正则表达式有点特别（我猜测可能出于性能方面的考量）：如果它们只包含 ASCII 字符（即所有字节的最高位都为 0），那么它们就以 US-ASCII 编码；否则它们就以定义它们的源代码文件的字符编码来编码。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sym_regex_encoding.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: UTF-8&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;名字&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/hello/&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/你好/&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby sym_regex_encoding.rb
&lt;span class="c"&gt;# 输出:&lt;/span&gt;
US-ASCII
UTF-8
US-ASCII
UTF-8
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;(3). 一个例外：&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;在字符串和正则表达式中，可以使用 &lt;code&gt;\uxxxx&lt;/code&gt; 或 &lt;code&gt;\u{x... x... x...}&lt;/code&gt; 来创建任意的 UNICODE 字符，如果一个字符串字面量或者正则表达式字面量中包含了 &lt;code&gt;\uxxxx&lt;/code&gt; 或 &lt;code&gt;\u{x... x... x...}&lt;/code&gt; 标记，且此标记所表示的字符不是 ASCII 字符，那么它的编码将设置为 UTF-8，而不管定义它的源代码文件的字符编码是什么。  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;unicode_notation.rb&lt;/strong&gt;:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: GBK&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"a"&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"中"&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s2"&gt;0061"&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\u&lt;/span&gt;&lt;span class="s2"&gt;2d4e"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby unicode_notation.rb
&lt;span class="c"&gt;# 输出:&lt;/span&gt;
GBK
GBK
GBK
UTF-8
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h2 id="虚拟编码 ASCII-8BIT"&gt;虚拟编码 ASCII-8BIT&lt;/h2&gt;
&lt;p&gt;Ruby 支持一个叫做 &lt;code&gt;ASCII-8BIT&lt;/code&gt; 的虚拟字符编码。这个虚拟编码更多地是用来处理二进制数据，或者在不确定 Ruby 代码文件编码时也可以将其指定为 &lt;code&gt;ASCII-8BIT&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id="编码转换"&gt;编码转换&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;(1). 可以将字符串从一个编码转换为另外一个编码&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;transcoding.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: UTF-8&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"中"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"GBK"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby transcoding.rb
&lt;span class="c"&gt;# 输出:&lt;/span&gt;
UTF-8
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"e4"&lt;/span&gt;, &lt;span class="s2"&gt;"b8"&lt;/span&gt;, &lt;span class="s2"&gt;"ad"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
GBK
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"d6"&lt;/span&gt;, &lt;span class="s2"&gt;"d0"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;zh_CN.UTF-8 &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 中 | &lt;span class="nb"&gt;od&lt;/span&gt; &lt;span class="nt"&gt;-An&lt;/span&gt; &lt;span class="nt"&gt;-tx1&lt;/span&gt;
&lt;span class="c"&gt;# 输出：&lt;/span&gt;
e4  b8  ad
&lt;span class="nv"&gt;LANG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;zh_CN.UTF-8 &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 中 | iconv &lt;span class="nt"&gt;-t&lt;/span&gt; GBK | &lt;span class="nb"&gt;od&lt;/span&gt; &lt;span class="nt"&gt;-An&lt;/span&gt; &lt;span class="nt"&gt;-tx1&lt;/span&gt;
&lt;span class="c"&gt;# 输出：&lt;/span&gt;
d6  d0
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;(2). 改变一个对象的编码&lt;/strong&gt;
    &lt;code&gt;encode&lt;/code&gt; 方法实际上是返回一个新的对象，而要改变一个对象的编码，则使用 &lt;code&gt;force_encoding&lt;/code&gt; 方法：    &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;force_encoding.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: ASCII-8BIT&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"中"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;force_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"UTF-8"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;force_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"GBK"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby force_encoding.rb
&lt;span class="c"&gt;# 输出:&lt;/span&gt;
ASCII-8BIT
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"e4"&lt;/span&gt;, &lt;span class="s2"&gt;"b8"&lt;/span&gt;, &lt;span class="s2"&gt;"ad"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
UTF-8
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"e4"&lt;/span&gt;, &lt;span class="s2"&gt;"b8"&lt;/span&gt;, &lt;span class="s2"&gt;"ad"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
GBK
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"e4"&lt;/span&gt;, &lt;span class="s2"&gt;"b8"&lt;/span&gt;, &lt;span class="s2"&gt;"ad"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;可以看到 &lt;code&gt;force_encoding&lt;/code&gt;只是改变了对象的字符编码，并没有改变存储字符的实际字节。&lt;/strong&gt; &lt;/p&gt;
&lt;h2 id="IO 的字符编码"&gt;IO 的字符编码&lt;/h2&gt;
&lt;p&gt;如果将一个某种特定字符编码的字符串输出到外部 IO 对象时，Ruby 将会使用什么编码输出这个字符串呢？答案取决于这个 IO 对象的编码是什么。&lt;br&gt;
每个 IO 对象都有两个和字符编码相关的属性：外部编码 &lt;code&gt;external_encoding&lt;/code&gt; 和 内部编码 &lt;code&gt;internal_encoding&lt;/code&gt;。  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(1). 输出过程中的编码转换&lt;/strong&gt;&lt;br&gt;
    与输出数据到一个 IO 对象这个过程相关的是 &lt;code&gt;external_encoding&lt;/code&gt;，输出过程中的字符编码转换规则为：若此 IO 对象的 &lt;code&gt;external_encoding&lt;/code&gt; 为 &lt;code&gt;nil&lt;/code&gt; ，则被输出的对象将不会被转换字符编码而直接输出其内存中的实际字节；否则，被输出的对象将使用 &lt;code&gt;external_encoding&lt;/code&gt; 进行编码，编码过程中所使用的源编码为被输出对象的 &lt;code&gt;encoding&lt;/code&gt; 属性。  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;output_transcoding.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="c1"&gt;# coding: UTF-8&lt;/span&gt;
&lt;span class="n"&gt;s_utf8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"中"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;s_utf8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;   &lt;span class="c1"&gt;# =&amp;gt; ["e4", "b8", "ad"]&lt;/span&gt;
&lt;span class="n"&gt;s_gbk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s_utf8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"GBK"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;s_gbk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;    &lt;span class="c1"&gt;# =&amp;gt; ["d6", "d0"]&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;s_gbk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;    &lt;span class="c1"&gt;# =&amp;gt;  #&amp;lt;Encoding:GBK&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;    &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;    &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;s_gbk&lt;/span&gt;      &lt;span class="c1"&gt;# =&amp;gt; 0xd6  0xd0 ， 说明 s_gbk 的字节没有经过编码转换而直接输出&lt;/span&gt;
&lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"UTF-8:Windows-31J"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;     &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Encoding:UTF-8&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;     &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Encoding:Windows-31J&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;s_gbk&lt;/span&gt;      &lt;span class="c1"&gt;# =&amp;gt; 0xe4  0xb8  0xad ，被正常转换为 UTF-8，说明数据输出过程中的编码转换和 internal_encoding &amp;lt;Windows-31J&amp;gt; 无关&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;(2). 输入过程中的编码转换&lt;/strong&gt;&lt;br&gt;
    当从一个 IO 对象读取数据时，读取的数据的编码和此 IO 对象的 &lt;code&gt;external_encoding&lt;/code&gt; 和 &lt;code&gt;internal_encoding&lt;/code&gt; 两个属性都有关系，具体的规则为：若 &lt;code&gt;internal_encoding&lt;/code&gt;  为 nil，那么外部数据将被不经任何转换地读进内存，在内存中存储此块数据的对象的 &lt;code&gt;encoding&lt;/code&gt; 属性被设置为此 IO 对象的 &lt;code&gt;external_encoding&lt;/code&gt;；否则，外部数据被读进内存时将被转换为 &lt;code&gt;internal_encoding&lt;/code&gt; 所标识的字符编码，且存储此块数据的对象的 &lt;code&gt;encoding&lt;/code&gt; 属性被设置为 &lt;code&gt;internal_encoding&lt;/code&gt;，编码转换所使用的源编码为 &lt;code&gt;external_encoding&lt;/code&gt;。  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;$'&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s1"&gt;e4&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s1"&gt;b8&lt;/span&gt;&lt;span class="se"&gt;\x&lt;/span&gt;&lt;span class="s1"&gt;ad'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tmp  &lt;span class="c"&gt;# 向 tmp 文件中输出“中”字经 UTF-8 编码的字节序列&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;tmp
&lt;span class="c"&gt;#输出：&lt;/span&gt;
中
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;input_transcoding.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt; &lt;span class="s2"&gt;"tmp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"r:UTF-8"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;   &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Encoding:UTF-8&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;   &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gets&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;   &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Encoding:UTF-8&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; ["e4", "b8", "ad"]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt; &lt;span class="s2"&gt;"tmp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"r:UTF-8:GBK"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Encoding:UTF-8&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Encoding:GBK&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gets&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Encoding:GBK&amp;gt;&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; ["d6", "d0"]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;(3). 设置 IO 对象的字符编码&lt;/strong&gt;&lt;br&gt;
    在使用 &lt;code&gt;IO.new()&lt;/code&gt;创建一个 IO 对象时，可以指定这个对象的 &lt;code&gt;external_encoding&lt;/code&gt; 和 &lt;code&gt;internal_encoding&lt;/code&gt;：  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;open_file.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="n"&gt;hello&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"w:gbk"&lt;/span&gt;
&lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s2"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"w:ISO8859-1:sjis"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby open_file.rb
&lt;span class="c"&gt;# 输出&lt;/span&gt;
&lt;span class="c"&gt;#&amp;lt;Encoding:GBK&amp;gt;&lt;/span&gt;
nil
&lt;span class="c"&gt;#&amp;lt;Encoding:ISO-8859-1&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;#&amp;lt;Encoding:Windows-31J&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;若要修改一个 IO 对象的 &lt;code&gt;external_encoding&lt;/code&gt; 和 &lt;code&gt;internal_encoding&lt;/code&gt;，使用 &lt;code&gt;IO#set_encoding()&lt;/code&gt; 方法：  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;set_enc.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;
&lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'gbk'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sjis:utf-8'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Shell Commands&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rvm use 2.0
ruby set_enc.rb
&lt;span class="c"&gt;# 输出&lt;/span&gt;
nil
nil
nil
nil
&lt;span class="c"&gt;#&amp;lt;Encoding:GBK&amp;gt;&lt;/span&gt;
nil
&lt;span class="c"&gt;#&amp;lt;Encoding:Windows-31J&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;#&amp;lt;Encoding:UTF-8&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;h3 id="IO 默认编码"&gt;IO 默认编码&lt;/h3&gt;
&lt;p&gt;Ruby 1.9+ 还有一个 IO 默认外部编码 &lt;code&gt;Encoding.default_external&lt;/code&gt; 和 IO 默认内部编码 &lt;code&gt;Encoding.default_internal&lt;/code&gt;的概念，不过通过我在 ruby-2.0.0-p247 上的实践，发现这个概念真是一团糟。总的来说，当你创建一个 IO 对象时，如果没有在 mode 参数里指定内部编码和外部编码，那么这个 IO 对象的内部编码和外部编码会分别设置为这两个默认编码，但是这需要满足以下规则：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;如果 &lt;code&gt;Encoding.default_internal&lt;/code&gt; 为 nil，那么用户创建的 IO 对象的内部编码和外部编码，与这两个默认编码没有关系，也就是说在这种情况下，即便是创建 IO 对象时没有指定内部编码和外部编码，Ruby 也不会用这两个默认编码的值去设置这个 IO 对象的内部和外部编码。&lt;br&gt;
&lt;strong&gt;例外：如果 IO 对象是以 readonly (如&lt;code&gt;File.new filename, "r"&lt;/code&gt;) 模式打开的，且没有指定内部编码和外部编码，那么不管&lt;code&gt;default_internal&lt;/code&gt;是否为 nil，那么该对象的外部编码都将被设置为 &lt;code&gt;default_external&lt;/code&gt; 的值。&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;如果 &lt;code&gt;Encoding.default_internal&lt;/code&gt; 和 &lt;code&gt;Encoding.default_external&lt;/code&gt; 的值相同（顺便提一下，&lt;code&gt;default_external&lt;/code&gt; 的值永远不会是 nil），那么如果创建 IO 对象时没有指定内部编码和外部编码，那么这个 IO 对象的外部编码将被设置为 &lt;code&gt;default_external&lt;/code&gt; 的值，而 IO 对象的内部编码不会被设置。&lt;/li&gt;
&lt;li&gt;如果 &lt;code&gt;default_internal&lt;/code&gt; 值不为 nil，且与 &lt;code&gt;default_external&lt;/code&gt; 不相等，创建 IO 对象时没有指定内部编码和外部编码，那么这个 IO 对象的外部编码将被设置为 &lt;code&gt;default_external&lt;/code&gt; 的值，内部编码被设置为 &lt;code&gt;default_internal&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;另外，当从一个 IO 对象读取数据时，如果该 IO 对象的 &lt;code&gt;external_encoding&lt;/code&gt; 和 &lt;code&gt;internal_encoding&lt;/code&gt; 都为 nil，那么外部数据将被不经任何转换地读进内存，在内存中存储此块数据的对象的 &lt;code&gt;encoding&lt;/code&gt; 属性被设置为&lt;code&gt;Encoding.default_external&lt;/code&gt;；&lt;/p&gt;
&lt;h4 id="设置默认编码"&gt;设置默认编码&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;可以通过 &lt;code&gt;Encoding.default_external=()&lt;/code&gt; 和 &lt;code&gt;Encoding.default_internal=()&lt;/code&gt; 来设置默认外部编码和默认内部编码。&lt;/li&gt;
&lt;li&gt;也可以通过 ruby 解释器的 &lt;code&gt;-E&lt;/code&gt; 选项来指定默认外部编码和默认内部编码。&lt;/li&gt;
&lt;li&gt;另外，Ruby 也会从 &lt;code&gt;LANG&lt;/code&gt; 环境变量推断默认的外部编码&lt;/li&gt;
&lt;li&gt;如果没有设置 &lt;code&gt;LANG&lt;/code&gt; 环境变量，也没有指定 &lt;code&gt;-E&lt;/code&gt; 选项，那么默认的外部编码就被设置为 &lt;code&gt;US-ASCII&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id="标准 IO 对象的默认编码"&gt;标准 IO 对象的默认编码&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;STDIN&lt;/code&gt;、&lt;code&gt;STDOUT&lt;/code&gt;和&lt;code&gt;STDERR&lt;/code&gt;这三个标准 IO 对象的外部编码和内部编码的默认值受 &lt;code&gt;Encoding.default_external&lt;/code&gt; 和 &lt;code&gt;Encoding.default_internal&lt;/code&gt; 控制，其规则和前文所述的 &lt;code&gt;default_external&lt;/code&gt;、&lt;code&gt;default_internal&lt;/code&gt; 对新建为指定编码的 IO 对象的控制规则一致。&lt;/p&gt;

&lt;p&gt;一个典型的例子：系统的 LANG 环境变量为 &lt;code&gt;zh_CN.UTF-8&lt;/code&gt;，且没有指定 ruby 解释器的 &lt;code&gt;-E&lt;/code&gt; 选项，那么这 3 个标准 IO 对象的内部编码和外部编码分别为：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;stdio_encoding.rb&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_external&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; UTF-8&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_internal&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;STDIN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; UTF-8&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;STDIN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;STDOUT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;external_encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;internal_encoding&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;</description>
      <author>lululau</author>
      <pubDate>Sat, 18 Jan 2014 02:44:30 +0800</pubDate>
      <link>https://ruby-china.org/topics/16856</link>
      <guid>https://ruby-china.org/topics/16856</guid>
    </item>
    <item>
      <title>[北京] 找一份 Ruby 或 Rails 的开发工作</title>
      <description>&lt;p&gt;工作 5 年，5 年间主要工作做 Java Web 开发，期间零碎地做过服务器管理，用 Bash/Ruby/Perl/Python 做工具开发，也用 Rails 和 Django 做过玩具级的小项目。&lt;/p&gt;

&lt;p&gt;喜欢 Ruby 和 Rails，想找一份 Ruby 或是 Rails 的开发工作。&lt;/p&gt;

&lt;p&gt;我的博客：&lt;a href="http://liuxiang.logdown.com/" rel="nofollow" target="_blank"&gt;http://liuxiang.logdown.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;我的 Github：&lt;a href="https://github.com/lululau/" rel="nofollow" target="_blank"&gt;https://github.com/lululau/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;我的简历：&lt;a href="http://liuxiang.logdown.com/pages/resume" rel="nofollow" target="_blank"&gt;http://liuxiang.logdown.com/pages/resume&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;有需要可以联系我：lululau@me.com&lt;/p&gt;</description>
      <author>lululau</author>
      <pubDate>Thu, 02 Jan 2014 22:08:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/16581</link>
      <guid>https://ruby-china.org/topics/16581</guid>
    </item>
    <item>
      <title>simple_form 的 :collection 选项生成的 radio_buttons / checkboxes 的样式问题</title>
      <description>&lt;p&gt;我用 simple_from（已生成 bootstrap wrappers) 生成的一个 radio_buttons 的表单控件：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= f.input :rating, :collection =&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:as&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:radio_buttons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:item_wrapper_class&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"radio-inline"&lt;/span&gt; &lt;span class="o"&gt;%&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;展示出来后，发现第一个 radio button 往下错位了一点：&lt;/p&gt;

&lt;p&gt;&lt;img src="//l.ruby-china.com/photo/2013/ae3b4cb01b063bc49c5b2da8ac3f2f58.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;发现是因为 simple_form（&lt;code&gt;SimpleForm::Inputs::CollectionRadioButtonsInput#apply_default_collection_options!&lt;/code&gt;）对每一个 wrap label  都有一个默认的 &lt;code&gt;radio&lt;/code&gt; 的 CSS class，&lt;code&gt;:item_wrapper_class&lt;/code&gt; 选项所指定的 class，不是用来替换这个默认的 class，而是合并到一块的，也就是说生成每个 radio button 的 HTML 是这样的：&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"radio radio-inline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"radio"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"1"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"product[rating]"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"product_rating_1"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"radio_buttons optional"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;1
&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;而 bootstrap3 里 &lt;code&gt;.radio&lt;/code&gt; class 里定义个一个 10px 的 top margin，另外还定义了 &lt;code&gt;.radio-inline + .radio-inline&lt;/code&gt; 的 &lt;code&gt;margin-top&lt;/code&gt; 为 0px，因此第一个 radio button 就会往下错 10 个 px，而第二个第三个都不会往下错。&lt;/p&gt;

&lt;p&gt;我现在的做法是在 &lt;code&gt;.radio-inline&lt;/code&gt; 里加了个 &lt;code&gt;margin-top: 0px&lt;/code&gt;，不知道这样会不会有问题，因为 simple_form 和 bootstrap3 都是简单地了解了一下，也不知道这个问题是不是我用的方法不对&lt;/p&gt;</description>
      <author>lululau</author>
      <pubDate>Thu, 05 Dec 2013 16:19:22 +0800</pubDate>
      <link>https://ruby-china.org/topics/16026</link>
      <guid>https://ruby-china.org/topics/16026</guid>
    </item>
    <item>
      <title>Ruby socket 库中的 BasicSocket#recv 方法的一个疑问</title>
      <description>&lt;p&gt;之前发现自己一遇到涉及到 TCP/IP 基础知识的问题时就抓瞎，所以决定好好学习一下 TCP/IP 的基础知识，把 UNP 的基础编程这部分粗略过了一遍，然后想回头过一遍 Ruby 的 socket 库的文档，并且希望能把 Ruby socket 库的用法和 UNP  中讲述的内容对应起来。当看到 BasicSocket#recv(maxlen, flags) 这个方法时，遇到了个问题。recv 方法的 flags 参数是一些标识选项，用于控制 socket 的行为，UNP 对 recv(2) 系统服务的 flags 的描述如下：&lt;/p&gt;

&lt;p&gt;&lt;img src="http://ww1.sinaimg.cn/large/78bff077jw1e899gqor9qj20ef064t9d.jpg" title="" alt="flags"&gt;
&lt;img src="http://ww3.sinaimg.cn/large/78bff077jw1e899gxns3cj20j503pdgk.jpg" title="" alt="MSG_DONTWAIT"&gt;&lt;/p&gt;

&lt;p&gt;UNP 中提到可能不是所有系统都支持这个 MSG_DONTWAIT 选项，我顺便查下了手册，OS X / Linux 中关于 recv(2) 的手册都没有提到 MSG_DONTWAIT 选项，Linux 的 recv(2) 手册中还提到 POSIX 只规定了 MSG_OOB, MSG_PEEK, and MSG_WAITALL 中三个选项，但是实际上 OS X 和 Linux 都定义了 MSG_DONTWAIT（grep MSG_DONTWAIT /usr/include/linux/socket.h  /usr/include/sys/socket.h），并且以下C语言和 Python 实现的服务器程序在设置 DONTWAIT 选项调用 recv 时，确实是表现出了 non-block 的行为（立即返回并抛出一个 EAGAIN）：&lt;/p&gt;

&lt;p&gt;C 版：&lt;/p&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/socket.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;arpa/inet.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;server_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client_fd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;socklen_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr_in&lt;/span&gt; &lt;span class="n"&gt;server_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;server_addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_family&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;server_addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;htons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6789&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;inet_aton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;server_addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;server_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;server_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_addr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client_addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;client_fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;client_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client_fd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MSG_DONTWAIT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sc"&gt;'\0'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"data: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Python 版：&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env python
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="n"&gt;server_sock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SOCK_STREAM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;server_sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6789&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;server_sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;client_sock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;client_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server_sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client_sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;MSG_DONTWAIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data: %s&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
    &lt;span class="n"&gt;client_sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;server_sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;而 Ruby 版的程序在调用 recv 时，却没有表现出来 non-block 的特性，而是一直阻塞在 recv 调用中知道接受到客户端发送过来数据为止：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"socket"&lt;/span&gt;

&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TCPServer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s1"&gt;'127.0.0.1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6789&lt;/span&gt;
&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept&lt;/span&gt;    
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Socket&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MSG_DONTWAIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# begin&lt;/span&gt;
    &lt;span class="c1"&gt;#     data = client.recv_nonblock 10&lt;/span&gt;
    &lt;span class="c1"&gt;# rescue Errno::EAGAIN&lt;/span&gt;
    &lt;span class="c1"&gt;#     retry&lt;/span&gt;
    &lt;span class="c1"&gt;# end&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"data: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;so, why ?&lt;/p&gt;

&lt;p&gt;顺便附上 Client 的代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"socket"&lt;/span&gt;

&lt;span class="n"&gt;sock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TCPSocket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="s2"&gt;"127.0.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6789&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;gets&lt;/span&gt;
    &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>lululau</author>
      <pubDate>Tue, 03 Sep 2013 14:11:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/13852</link>
      <guid>https://ruby-china.org/topics/13852</guid>
    </item>
    <item>
      <title>instance_eval 是如何做到修改 Block 里的 self 引用的？</title>
      <description>&lt;p&gt;比如这段代码&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;world&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;world&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_eval&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Object
Object
Person
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果我想写一个叫做&lt;code&gt;haha&lt;/code&gt;方法，然后通过的调用 &lt;code&gt;p.haha {puts self.class}&lt;/code&gt; 输出 &lt;code&gt;Person&lt;/code&gt;，如果不借助 &lt;code&gt;instance_eval&lt;/code&gt; (包括不借助那些已经借助了&lt;code&gt;instance_eval&lt;/code&gt;的方法：&lt;code&gt;Module#define_method&lt;/code&gt; 等)，可以写出这个 &lt;code&gt;haha&lt;/code&gt;  方法吗？说到底就是像 &lt;code&gt;instance_eval&lt;/code&gt; 那样修改一个 Block 里的 self 引用是可行的吗？&lt;/p&gt;</description>
      <author>lululau</author>
      <pubDate>Thu, 29 Aug 2013 11:25:45 +0800</pubDate>
      <link>https://ruby-china.org/topics/13717</link>
      <guid>https://ruby-china.org/topics/13717</guid>
    </item>
    <item>
      <title>在 action 里调用一个耗时很长的外部命令时，整个应用都被卡死的问题</title>
      <description>&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class PeopleController &amp;lt; ApplicationController
  # GET /people
  # GET /people.json
  def index
    @people = Person.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render :json =&amp;gt; @people }
    end
  end

  # GET /people/1
  # GET /people/1.json
  def show
    @person = Person.find(params[:id])
    system "sleep 1000000"
    respond_to do |format|
      format.html # show.html.erb
      format.json { render :json =&amp;gt; @person }
    end
  end

  ....

end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上面的代码所示，名为 show 的 action 里，调用了"sleep 1000000"，然后整个应用全部卡死了，不管通过浏览器访问哪个 action 都不返回。&lt;/p&gt;

&lt;p&gt;请教这个问题怎么解决？&lt;/p&gt;</description>
      <author>lululau</author>
      <pubDate>Tue, 19 Feb 2013 15:08:02 +0800</pubDate>
      <link>https://ruby-china.org/topics/8768</link>
      <guid>https://ruby-china.org/topics/8768</guid>
    </item>
    <item>
      <title>请教个 Ruby 的基础问题</title>
      <description>&lt;p&gt;方法“attr_accessor”和“module_function”同样都是类"Module"的实例方法，但是为什么“attr_accessor”可以在定义类的时候这样用：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hello&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:hello&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;而“module_function”却不可以这样用呢：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hello&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;module_function&lt;/span&gt; &lt;span class="ss"&gt;:hello&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我觉得唯一合理的解释就是类“Class”在继承类“Module”的时候，把方法“module_function”给删除了？  &lt;/p&gt;</description>
      <author>lululau</author>
      <pubDate>Fri, 20 Apr 2012 23:15:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/2785</link>
      <guid>https://ruby-china.org/topics/2785</guid>
    </item>
    <item>
      <title>哪里能找到关于 ri 文档格式的说明文档</title>
      <description>&lt;p&gt;问题是这样的，最近一段时间安装的所有的 gems 在查看其文档时，都会报一个错误：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/rdoc/ri/ri_reader.rb:54:in &lt;span class="sb"&gt;`&lt;/span&gt;initialize&lt;span class="s1"&gt;': No such file or directory - /Library/Ruby/Gems/1.8/doc/uuid-2.3.4/ri/UUID/cdesc-UUID.yaml (Errno::EENOENT)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好像 ri 需要一个 cdesc-CLASSNAME.yaml 一个说明文件，但是我发现最近安装的 gems 里都没有这个问题，取而代之的时 cdesc-CLASSNAME.ri 文件，而早先安装的 gems 里都有那个 yaml 文件。而如果我先把早先安装的一个 gems 卸载然后重新安装，发现那个 yaml 文件也没有了。&lt;/p&gt;

&lt;p&gt;谁知道这是怎么回事吗？&lt;/p&gt;

&lt;p&gt;或者哪里有关于 ri 文档格式的说明文档？  &lt;/p&gt;</description>
      <author>lululau</author>
      <pubDate>Tue, 10 Jan 2012 18:25:08 +0800</pubDate>
      <link>https://ruby-china.org/topics/808</link>
      <guid>https://ruby-china.org/topics/808</guid>
    </item>
  </channel>
</rss>
