<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Niatruc (zbh)</title>
    <link>https://ruby-china.org/Niatruc</link>
    <description/>
    <language>en-us</language>
    <item>
      <title>实例变量的一个坑</title>
      <description>&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;  &lt;span class="nc"&gt;C&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;
    &lt;span class="vi"&gt;@c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt;  &lt;span class="nf"&gt;f&lt;/span&gt;
      &lt;span class="vi"&gt;@c&lt;/span&gt; 
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;f&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如上代码，当我自以为是地认为&lt;a href="/c" class="user-mention" title="@c"&gt;&lt;i&gt;@&lt;/i&gt;c&lt;/a&gt;是类 C 的实例变量时，结果却非我想象的那样（期望&lt;code&gt;C.f&lt;/code&gt;结果为 1，实际为 nil）
翻开笔记复习、巩固一下以前所学的 Ruby 内部机制。
原来，&lt;code&gt;class &amp;lt;&amp;lt; C&lt;/code&gt;打开了 C 的元类，所以从&lt;code&gt;class &amp;lt;&amp;lt; C&lt;/code&gt;到它的&lt;code&gt;end&lt;/code&gt;之间的作用域是 C 的元类的作用域，于是乎&lt;a href="/c" class="user-mention" title="@c"&gt;&lt;i&gt;@&lt;/i&gt;c&lt;/a&gt;就成了 C 的元类的实例变量：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singleton_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class_eval&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="vi"&gt;@c&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;顺便自卖自夸一波自己正在做的一个查询和操作数据库的工具。做这个东西的起因是，之前做开发的时候，插入测试用的数据要么用 navicat 之类的工具手动地一行一行录入，要么写 sql 脚本批量插入，都不是那么方便，又找不到其他好办法，有点烦；另外有时项目涉及到多个不同类型的数据库（mysql/oracle/hbase 等），又没有比较好的集大成的工具（navicat 有集合多种数据库管理功能的版本，没用过；有一个叫 squirrel 的，用起来不是那么好，卡 bug……），于是促成了爱撸码的我的小小主意——自己设计一个命令行数据库工具，挣脱 sql 语句的束缚，自己搞一套规则&lt;img title=":alien:" alt="👽" src="https://twemoji.ruby-china.com/2/svg/1f47d.svg" class="twemoji"&gt; 于是乎，借鉴 ActiveRecord、Sequels 等框架的思想，利用 Ruby 语法灵活多变的特性，自己开搞一套，也可以多练习用 Ruby 撸码。现在做好了 mysql 的查询功能，以及一些命令行补全功能，后面找时间做‘增删改’的功能。效果如下：&lt;/p&gt;

&lt;p&gt;补全操作，从库名到表名到对表的操作命令名：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/55ddb3ba-3622-45d3-b04d-e1ec98dfc7a5.gif!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;‘cd’操作，进入到库/表的上下文：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/7e4291c9-2204-4c9d-9d80-a74bdb6ac3cc.gif!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;条件查询，用散列封装：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/08a46e6e-a529-489c-aa04-e97e5770bd86.gif!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;项目链接：&lt;a href="https://github.com/Niatruc/zombiehome" rel="nofollow" target="_blank"&gt;https://github.com/Niatruc/zombiehome&lt;/a&gt;
路过的老铁支持支持哈哈谢谢谢谢~&lt;img title=":alien:" alt="👽" src="https://twemoji.ruby-china.com/2/svg/1f47d.svg" class="twemoji"&gt; &lt;/p&gt;</description>
      <author>Niatruc</author>
      <pubDate>Sun, 16 Dec 2018 22:38:44 +0800</pubDate>
      <link>https://ruby-china.org/topics/37905</link>
      <guid>https://ruby-china.org/topics/37905</guid>
    </item>
    <item>
      <title>获取 BasicObject 实例的 binding</title>
      <description>&lt;p&gt;想得到一个 BasicObject 的实例的 binding，但是 BasicObject 的实例方法中没有 binding，于是下面的代码行不通：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;BasicObject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

&lt;span class="n"&gt;bo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_exec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;binding&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; NameError: undefined local variable or method `binding' for #&amp;lt;BasicObject:0x2e570ded&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;从 &lt;a href="https://bugs.ruby-lang.org/issues/5360" rel="nofollow" target="_blank"&gt;https://bugs.ruby-lang.org/issues/5360&lt;/a&gt; 这个帖子里得到了解决方法：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_exec&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;binding&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>Niatruc</author>
      <pubDate>Sun, 16 Dec 2018 21:43:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/37904</link>
      <guid>https://ruby-china.org/topics/37904</guid>
    </item>
    <item>
      <title>关于 Open3.popen3 方法的使用问题的请教</title>
      <description>&lt;p&gt;我在一个 ruby 程序中使用 Open3.popen3 这个方法打开另一个 ruby 程序 t1，并通过 io 流向另一个程序 t2 传递数据，而另一个程序使用 gets 方法来获取这些数据，如下：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# t1.rb&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"open3"&lt;/span&gt;

&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;thr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Open3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;popen3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"jruby D:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;jruby-9.1.12.0&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;test&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;emtest&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;t2.rb"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 通过i传数据给子进程&lt;/span&gt;
&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"asdf"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'主进程'&lt;/span&gt;

&lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"从子进程来的数据：&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"end1"&lt;/span&gt;
&lt;span class="n"&gt;thr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"end2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# t2.rb&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;puts&lt;/span&gt; &lt;span class="s2"&gt;"123"&lt;/span&gt;
&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&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;gets&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;puts&lt;/span&gt; &lt;span class="s2"&gt;"rrr&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后我在控制台窗口运行程序 t1，之后就这样一直卡着：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/69100214-a6a4-4820-b7ad-6b905834f5ac.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;似乎程序 t2 中的 gets 方法并被没有取到数据而把程序阻塞了&lt;img title=":joy:" alt="😂" src="https://twemoji.ruby-china.com/2/svg/1f602.svg" class="twemoji"&gt; 请问各位大佬，这种情况要怎么办，是哪里的代码写错了？&lt;img title=":joy:" alt="😂" src="https://twemoji.ruby-china.com/2/svg/1f602.svg" class="twemoji"&gt; &lt;/p&gt;</description>
      <author>Niatruc</author>
      <pubDate>Sun, 24 Jun 2018 16:46:39 +0800</pubDate>
      <link>https://ruby-china.org/topics/37039</link>
      <guid>https://ruby-china.org/topics/37039</guid>
    </item>
    <item>
      <title>一个字符编码问题</title>
      <description>&lt;p&gt;假设 a 是一个“ASCII-8BIT”编码的字符串变量，u 是一个“UTF-8”编码的字符串变量（但是其中包含\x**这样的字符），a+u 就会报”编码不兼容”的错误。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;192&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;168&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="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;pack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"C*"&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;a&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:ASCII-8BIT&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\xff\xff\xff\xff\xff\xff&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;u&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="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;  &lt;span class="c1"&gt;#=&amp;gt; Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看来也许\x**这样的字符是只有一个字节的，遇到两个字节作一个字符的 UTF-8 编码就会出问题。
……但是 ruby 这个报错信息很模糊啊，让人一直误以为出错是因为这两种编码的字符串是不能做连接运算的（其实可以！！）。&lt;/p&gt;</description>
      <author>Niatruc</author>
      <pubDate>Wed, 19 Apr 2017 11:11:56 +0800</pubDate>
      <link>https://ruby-china.org/topics/32818</link>
      <guid>https://ruby-china.org/topics/32818</guid>
    </item>
    <item>
      <title>偶然发现 ruby 闭包的一个问题</title>
      <description>&lt;p&gt;刚刚偶然发现 ruby 闭包的一个问题，我的代码简化后如下，&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:f1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="ss"&gt;:f2&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;each&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="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
        &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我想让 f1 和 f2 两个方法使用环境中的变量 i，期待的结果是这样的：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;f1&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 0&lt;/span&gt;
&lt;span class="n"&gt;f2&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 10&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;f1&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 10&lt;/span&gt;
&lt;span class="n"&gt;f2&lt;/span&gt; &lt;span class="c1"&gt;#=&amp;gt; 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;莫非这意味着定义 f1，f2 这两个方法时使用的块共享了堆中同一片变量空间（其中包含变量 j）？
有没有深入了解 ruby 解释器的伙伴解释解释呗~如果我想达到我要的结果，有没有好的写法？&lt;/p&gt;</description>
      <author>Niatruc</author>
      <pubDate>Fri, 30 Dec 2016 22:55:39 +0800</pubDate>
      <link>https://ruby-china.org/topics/32030</link>
      <guid>https://ruby-china.org/topics/32030</guid>
    </item>
  </channel>
</rss>
