RVM Ruby 1.9.3 p125 安装 ruby-debug19 出错的解决办法

四月 1st, 2012 § 0 comments § permalink

初学 RoR ,竟然在环境配置的地方被难住了两回。

第一回是安装完 RVM 后要在 RVM 中的 Ruby 里安装 Rails ,不知道为什么总是调用到系统的 gem ,后来才知道需要 source 一下 $HOME/.rvm/script/rvm 。

第二回就是这么件事情了,在 Gemfile 里取消掉 ruby-debug19 的注释后, bundle 一下竟然没有办法顺利安装。

搜索与尝试后的结果是,先输入以下两条命令,其实就是 gem build 包的一些参数啦:

bundle config build.linecache19 --force --with-ruby-include="$rvm_path/src/ruby-1.9.3-p125/"
bundle config build.ruby-debug-base19 --force --with-ruby-include="$rvm_path/src/ruby-1.9.3-p125/"

输入这两条命令以后,再 bundle 一下,基本上就能安装了。

如果不是 1.9.3-p125 版本的,应该把最后的路径改一下就行了。

其实我还是有点不知所以然,起作用的究竟是 –force 参数还是 –with-ruby-include 参数。

感谢以下三篇文章:

RVM 下安装 GEM 编译失败 LINECACHE19

ROR debug 环境搭建

rvm ruby-1.9.3 安装 ruby-debug

2012.4.7 Update: 原来安装不成功的原因是 ruby-debug19 压根就不和 1.9.3 兼容,所以起作用的是 –force 参数。

正确安装的做法是在 Gemfile 里干掉 ruby-debug19 的那一行,换成 debugger ,之后 bundle install

2012.2.19

二月 19th, 2012 § 0 comments § permalink

话说回来,我一个月前一直在做的某个html5版的豆瓣电台终于(也许)正式搁浅了。

具体原因其实可以从 Github 上看的,主要是因为实现“纯前端”需要依赖 Yahoo 提供的 YQL 把豆瓣电台 API 返回的 JSON 数据变成 JSONP 的形式。然后,嗯,似乎豆瓣电台把 YQL 的 IP 干掉了,每次都说 403。那就只好暂停下来了……

好吧,很难想象某个以个人兴趣为导向的项目搁浅了自己还要写篇文章奠祭一下。

原来项目是用 CoffeeScript 写的,不过后来觉得每次测试都要编译一把实在是让人蛋疼的紧,就又用了 seajs 来管理模块。

这下就轻松多了,seajs 有 CoffeeScript 的插件,自己测试的时候就省事了许多。

不过后来又觉得每次都要 F5 太过于损键盘,所以想起来之前看过一个介绍 Backbone 的 View 的视频(需翻墙)里似乎有一个软件是当检测到前端文件有变动时通过 WebSocket 通知浏览器自动刷新的程序,叫做 livereload ,这是一个原理简单但是让人极为喜爱的应用啊。

可惜的是,livereload 2 只有 Mac 端和 Windows 端。

难道使用 Linux 的前端开发者就这么不招人待见么Orz……找了一下其他的 livereload 实现,发现了两个版本,分别是 guard-livereload 和 node-livereload ,嗯,第一个还是 Ruby 写的,而且我装了以后也不会用……没什么说明书啊……我猜是需要和 ROR 配合使用的……第二个,你猜对了,是用 NodeJS 写的。其实之前在找的时候我就想到了,虽然我没怎么用 NodeJS 写过程序,但是我看过 API 文档,记得似乎 fs 模块提供了一个监控文件变动的 API ,这玩意儿天生就是用来实现 livereload 的啊!

唯一可惜的是,这个包似乎从2011年的6月份以后就再也没有更新过了……

与此同时,我试用了一下,还是不会用……

好吧,我 fork 了一份,看源码没有多少,打算自己研究研究。

话说回来,嗯,又说回来了。自己用了 seajs ,感觉很不错,可惜的是 spm 里提供的包太少……我打算什么时候给它加个老赵的 jscex 库进去,这个库是用来调整 JavaScript 的非阻塞特性的。

话说我自己都没怎么用过来着……

语音搜索,穷人的语音输入

二月 16th, 2012 § 0 comments § permalink

webkit 内核浏览器支持 Input 标签的 x-webkit-speech 大概从来都不是秘密。

不过我想的是,希望能够用这个来做个语音输入。

嗯,基本没有难点,做了个简单的 jQuery 插件,以下是从 CoffeeScript 转过来的代码:

(function() {
 
  jQuery.fn.voiceInput = function() {
    var inputElem,
      _this = this;
    if (jQuery.browser.webkit) {
      this.wrap('<div class="voice-input-area">').after("<input class=voice-input type=text x-webkit-speech=x-webkit-speech />");
      inputElem = this.parent('.voice-input-area').find('input').css({
        border: "none",
        color: "transparent",
        width: function() {
          return $(this).css("font-size");
        }
      });
      return inputElem.on('webkitspeechchange', function() {
        return _this.append(inputElem.val());
      });
    }
  };
 
}).call(this);

使用方法

<textarea class='need-voice-input'></textarea>
<script>
    $('.need-voice-input').voiceInput();
</script>

demo的话就看我的评论框吧。

一些其他的关于 x-webkit-speech 属性的内容:http://liumiao.me/html/wd/W3C/264.html

写在 2011 之后

一月 2nd, 2012 § 0 comments § permalink

回头翻看一下这一年写的博客,我没有怎么计算文章的数量,但显然不算多。

我不是一个特别爱写东西的人,看不出来吧~

回头看这一年的经历,发现目前赖以骗钱的两门手艺: Python 和 JavaScript 其实严格来说都是今年真正开始学的。除此之外,Linux 的发行版从 Ubuntu 换到了 ArchLinux,手中的编辑器几经改变,终于落回了 Vim(不过赞一句,subline text 2 真心不错),买了/看了几本关于 Python 及 JavaScript 的书,linux kernel 版本从 2.6.4 飙到了 3.1.6 (是的,我刚刚 sudo pacman -Syua 了,3.1.6 了!),同时,还骗了个前端实习生的职位。

之前定下的目标:前端攻城湿,正在慢慢的步入正轨,虽然步伐缓慢,但我想我还是可以继续前行。

接下来的一段时间,主要要做的事情大致就是磨练手头上的两门手艺,具体来说

  • 了解一下 HTML5 游戏开发方面的内容
  • 解决从 2011 年拖到了 12 年的博客程序的一些问题
  • 阅读 Bottle Web Framework 和 jQuery 的源代码
  • 看完手头上的那几本范围颇广的书
  • 换个公司(对淘宝还是垂涎啊……)

然后?然后我还有一长串的 Todo 在 todoist 里。

2011.12.30 JavaScript 笔记

十二月 30th, 2011 § 0 comments § permalink

昨天已经把 underscore.js 变成了 underscore.js.coffee ,基本上也可以拿 CoffeeScript 操刀上阵了。

接下来的想法是把 underscore.js 里扩展的,和 CoffeeScript 的语法糖冲突的 API 给剔除,这样就差不多了。

当然,这篇文章不是为了说这个。依旧是记录一些在看 underscore.js 源代码时的笔记。

JavaScript 中的操作符 in

在 underscore.js 的源码里有这么一句:

if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false;

我记得 ECMAScript 的规范里是没有 in 操作符的,第一次看到这个用法的时候我翻了好几遍新买的 《JavaScript 高级程序设计》,当然,也有可能翻的时候太过于粗心,所以确实没有在书里发现。

后来查到在 MDN 里倒是有相关资料:https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special_Operators/in_Operator

与此同时,经过 IETester 的测试,这个操作符在 IE6 中同样也是能够使用的(废话,不然人家 Underscore.js 也不会用啊)。

undefined 和 void 0

在测试 CoffeeScript 编译为 JavaScript 的途中,我发现编译器会把 undefined 改写成 void 0 ,所以查了一下相关的资料。感谢 Stack Overflow ,我在其中找到了回答:
http://stackoverflow.com/questions/4806286/difference-between-void-0-and-undefined

结论是:

      void 0 和 undefined 没有区别,void 是一个操作符(MDN),void 0 就会返回 undefined
      void 0 的字数比 undefined 字数少。不要笑!压缩的时候每个字母都是宝啊!
      在进行比较时,使用 void 0 比使用 undefined 效率更高。这里 是其中一位仁兄使用的测试代码,至于结果,可以去 Stack Overflow 上看

2011.12.28 依旧是关于 CoffeeScript 和 Underscore.js

十二月 28th, 2011 § 0 comments § permalink

关于 CoffeeScript 的变量作用域控制

最近的感觉是, CoffeeScript 的作用域控制做的很不错,可惜在把原生 JavaScript 改写成 CoffeeScript 时容易让人纠结。

比如 Underscore.js 源码中的:

 
  // Returns a function, that, when invoked, will only be triggered at most once
  // during a given window of time.
  _.throttle = function(func, wait) {
    var context, args, timeout, throttling, more;
    var whenDone = _.debounce(function(){ more = throttling = false; }, wait);
    return function() {
      context = this; args = arguments;
      var later = function() {
        timeout = null;
        if (more) func.apply(context, args);
        whenDone();
      };
      if (!timeout) timeout = setTimeout(later, wait);
      if (throttling) {
        more = true;
      } else {
        func.apply(context, args);
      }
      whenDone();
      throttling = true;
    };
  };

改写成 CoffeeScript 的话,预先声明的方法就有点纠结了,以下是我的 CoffeeScript:

 
    # Returns a function, that, when invoked, will only be triggered at most once
    # during a given window of time.
    _.throttle = (func, wait) ->
        context = args = timeout = throttling = more = undefined
        whenDone = _.debounce ->
            more = throttling = false
        , wait
        return ->
            context = @
            args = arguments
            later = ->
                timeout = null
                func.apply context, args if more
                whenDone()
            timeout = setTimeout later, wait unless timeout
            if throttling then more = true else func.apply context, args
            whenDone()
            throttling = true

当然,相比于 JavaScript 那混乱的变量作用域,无疑还是这么干比较安全。

不过,到底还有没有更好的解决方案呢……

这是关于 CoffeeScript 的。

关于 Underscore.js

我在看 1.2.3 版本的源码时(2011.12.28 的最新版本是 1.2.3),频繁的看到一个相似的语句:

for (var key in obj) {
    if (hasOwnProperty.call(obj, key)) {
        keys[keys.length] = key;
    }
}

当然,我稍微格式化了一下,我在意的是 keys[keys.length] = key;

我想不明白这个语句和 keys.push(key) 究竟有什么不同。

有趣的 JavaScript

十二月 27th, 2011 § 1 comment § permalink

这段时间在作什么呢,第一是在折腾 CoffeeScript ,第二是在看 Underscore.js ,第三是买了两本书《JavaScript 修炼之道》和《JavaScript 高级程序设计》。

我果然是个挖坑不填的家伙啊,《程序员修炼之道》还没看完呢……

关于 《JavaScript 修炼之道》

《JavaScript 修炼之道》是一本很薄的书,由于《JavaScript 语言精粹》还没到,所以我不好对比两者的厚薄程度,不过想来两者都是差不多的。

《JavaScript 修炼之道》算是一本比较浅显的入门提高书,说是入门提高,在我看来其实应该就是入门书。

唯一作了笔记的部分是:

可以利用 JavaScript 的方括号操作符我们可以做到动态的调用方法及熟悉,比如

    window['history'] = ...

由于传入的是一个字符串,所以几乎所有结果能够获得字符串的代码都能在方括号里使用,比如:

    window[isHistory?'history':'other']
    window[(enable?'add':'delete')+'action']
    window[{firstName:'foo',lastName:'bar'}[needFirst?'firstName':'lastName']]

值得注意的是,如果你在向方法传递的参数上大量使用这个技巧,将使代码变得难以阅读,此时使用常规的 if/else 结构更加明智

所以说,如果你已经到了对 JavaScript 有一些心得的时候,就不需要再看这本书了,看其他书应该更合适一些。

关于 CoffeeScript

CoffeeScript 是一门为了编译成 JavaScript 而诞生的语言,推荐者的说法是保留了 good part of javascript ,规避了不好的部分。

我不怎么苟同。

CoffeeScript 几乎摈弃了大部分的括号,用空格代替,但是在有些链式的写法中,倘若不使用括号就会使得编译成的 JavaScript 与原意大相径庭,一旦使用了括号以后,会让代码看起来突然就变得丑陋起来。

CoffeeScript 的语法糖是很多使用者上贼船的驱动力之一,不过个人觉得语法糖过多了点,比如 if not 和 unless ,我觉得完全没有出现 unless 的必要么……

什么?你问我还有什么不喜欢的?好吧,没有了。CoffeeScript 我很喜欢。

我最近在用 CoffeeScript 重写 Underscore.js ,虽然可以用 js2coffee 这个工具,但在我看来还是比不上经过大脑加工以后的 CoffeeScript。嗯,既看源码又玩玩 CoffeeScript,确实是件愉悦的事情。

关于 Underscore.js

关于 Underscore.js ,唯一不满的地方是直接改原型不就好了么……竟然还要弄个 _ 对象出来……

我的进度不快,目前只写完了 // Collection Functions 一块,觉得有趣的部分是两句代码:

    computed >= result.computed && (result = {value : value, computed : computed});
    if (result || (result = iterator.call(context, value, index, list))) return breaker;

如果&&的第一个运算数是false,就不再考虑第二个运算数,直接返回false;如果||的第一个运算数是true,也不再考虑第二个运算数,直接返回true。

因此,这两个运算符也可以使用在简化选择性执行语句的操作中(据我所知,这个在其他语言中(Python/C#)也是如此,然而我在阅读其他语言的源码时却鲜有遇见这样的代码,不知为何)。上面的两句代码可以翻译成下面的代码:

if (computed >= result.computed) {
    result = {value : value, computed : computed};
}
 
if (!result) {
    result = iterator.call(context, value, index, list);
}
if (result) {
    return breaker;
}

有兴趣可以看一下这篇文章 《JS的&&和&,||和|运算符两个不同点》

以及一些其他的

查 Infinity 时查到的, 《奇怪的js NaN and Infinity》

//Parsing something that isn't a number results in NaN. isNaN helps to detect those cases:
parseInt("hello", 10) // NaN
isNaN(parseInt("hello", 10)) // true
 
//Division through zero results in Infinity:
1 / 0 // Infinity
 
//Both NaN and Infinity are of type "number":
typeof NaN // "number"
typeof Infinity // "number"
 
//Note that NaN compares in a strange way:
NaN == NaN // false (!)
//But:
Infinity == Infinity // true

2011.12.19 笔记

十二月 19th, 2011 § 0 comments § permalink

这段时间颇为紧张,一进入 12 月份竟然发现诸多事情都凑在了一块儿,从 4 号去上海参加 PyCon 到 14 号又去上海参加 Burning Guru Fuel ,中途又因为实习的公司双 12 的事情去临平帮了几天的忙,一个月的时间几乎快有半个月是在旅馆过的夜。

我忽然觉得这个月自己真的有那么点流浪汉的感觉。

可惜这次 Burning Guru Fuel 的定向越野的时间实在是有些紧迫,以至于都没有好好端详一下主办方精心准备的 20 个颇有味道的点。实在有些可惜。

这次上海之旅认识了两个 93 年出生的互联网小伙,名字叫做孙明和孙亮,是有点属于那种我欣赏且想要成为而目前还没有成为的人。

他们很出色。

当然,也有可能他们没有我想象的那么好。不过我相信这种事情他们和我应该都不会介意。

这次出行是一个很不错的体验,孙明和孙亮给我的触动很大。

当然,还有就是定向越野的最后一个特殊任务,算是一堂挺深刻的教育。

如果我不想做,那就不要再做了,那是真的毫无意义。

浏览器img标签底部的多余像素

十一月 30th, 2011 § 0 comments § permalink

许久没有写文章了,这次的文章依旧只是一个小品。

从来只知道死而不僵的 IE6 的 img 标签底部有多5像素的 BUG ,哪里想到,今天在做一个页面的时候发现,其他浏览器其实都有这个状况出现。

原来还没有想到这个问题,还妄图用触发块级格式化范围的办法来解决这个问题(虽然看起来确实有点用这个解决的样子),等到实在没办法了才想起来,似乎 IE6 里有过这种状况,只不过 IE6 里是5像素,而 chrome 里是3像素……

难道 W3C 里规定了 img 的底部有3像素左右的占位?

下面是测试用的页面:

测试页面

2011.12.30 Update

一般来说,可以先尝试一下给图片使用 display:block 属性,基本就能够解决问题。

Archlinux 安装 aliedit

十月 20th, 2011 § 0 comments § permalink

在 AUR 上的 aliedit 需要 libpng12 。

但是我的系统上不知道为什么,无法编译 AUR 上的 libpng12 。

看 AUR 上的评论所说,其实并不需要 libpng12 ,只是需要 libpng12.so.0 这个文件罢了。

所以软链接 /usr/lib/libpng14.so 。

sudo ln -s /usr/lib/libpng14.so /usr/lib/libpng12.so.0

然后

yaourt aliedit

询问 Edit PKGBUILD ? [Y/n] 时选择 Y ,注释掉

depends=('libpng12')

然后正常安装即可~