几个语言中的迭代器

上次有朋友说python的迭代器很好用,就是不好理解,我说其实php也有迭代器的,只是很多人不知道而已。

python迭代器:

先说说python的迭代器,python的迭代器使用yield关键字来实现,可以被for调用。

还是来拿读文件来说事,我们有一个文件,里面的数据都是TAB分隔,如果我们想实现一个一行行读取的库核心的地方可以使用迭代器来写:

tab文件(html输出后估计tab变成了空格,复制的同学请注意):

迭代器代码:

这里涉及迭代器的部分在于read方法中的yield迭代器,虽然是for循环,在yield调用一次以后会挂起等待下一次调用yield,所以很多人在这里需要理解很久。所以yield在while内自然也是一样的效果。

继续阅读

sinatra “incompatible character encodings: ASCII-8BIT and UTF-8”问题

使用sinatra的时候出现了“incompatible character encodings: ASCII-8BIT and UTF-8”报错。这个应用是使用haml并且在haml里使用markdown方法去读markdown文件来作为模板解决方案的,如果Tilt读取haml是一种编码格式而rdiscount读取markdown是另一种编码,应该会产生这问题,于是google了一下,找到如下一个解答:

Incompatible character encoding in simple Sinatra app

其原因大概是Tilt使用了IO.binread读取后编码为ASCII-8BIT,而RDiscount则读取文件后转换为需要的编码格式,但如果需要的格式是ASCII-8BIT时就会失败,它直接把utf-8编码的字符串传给了Tilt。此类问题出现在ruby1.9+的版本上。可以通过使用File.read代替Tilt默认的IO.binread,或者读取完后强制转换成你需要的编码格式:

示例代码:

示例中使用的是erb模板,haml也是一样的,我使用force_encoding的解决方案,运行通过。

我遇到问题时各个包版本如下:

  • ruby:2.0.0
  • Tilt:1.3.6
  • rdiscount:2.0.7.1

我的某个服务器就没出现这问题,应该是和某些版本有关的。

ruby1.9或2.0 irb不支持中文的解决

今天重新编译了一下ruby,发现irb输入不了中文了,出现类似如下的字符串:

'\U+FFE4\U+FFB8\U+FFAD\U+FFE6'

google了一下发现是readline的问题,似乎只有mac下才有这问题。于是重新编译一次,把readline的地址制定到 --with-opt-dir=/path/to/your/readline。

编译安装后就会发现一切都解决啦。

ruby动态创建类和方法

很多人通过Class.new和define_method方法来动态创建类和方法。

怎么创建到执行时才知道类名的类呢,答案是const_set方法,将这个常量和类连接在一起,放在Object下面就可以了。定义方法自然是define_method,以下是示例代码:

大致情况就这些,大家可以根据自身情况使用。

使用EventMachine

译自:Playing with eventmachine

最近这几周,我在工作中用了好几次 Ruby EventMachine,虽然它的 RDoc 还不错,但要是真想搞明白这玩意儿恐怕还是要花些功夫,所以我就写了这篇文章。

首先要弄明白的是,究竟什么是EventMachine,在什么场景会用到它。简而言之,EM(EventMachine)是个事件循环监听器(Event loop)。一旦你使用了EventMachine,它便随着ruby的主线程启动,然后去做他自己该做的事情。EM可以监听sockets、监听文件描述符、控制定时器等大量的事情。当你监听的事件触发时,EM会触发你的回调方法,如此一来你便可以处理这些事件,处理完之后再把事件控制权交还给EventMachine。

你也可以让EventMachine执行一大堆和你主要逻辑无关的代码,当这一大堆代码执行完的时候再让回调方法在主要逻辑连接上的任何请求上执行。

我们来用一段代码增进对它的理解:

例1.定时器:

我们来瞧一下这段简单的代码吧。在程序执行之前,需要先安装好 Eventmchine,我们可以通过rubygems来安装(gem install eventmachine),然后我们在程序里引入需要的部分(require 'eventmachine')。你可能会奇怪为什么我有的地方用了EventMachine,有的地方用了EM,其实他们是一样的,你可以随意对调。EM写起来比较短,不过我有时候也会用EventMachine。EventMachine#run方法用来开启主事件循环监听,在这段代码块里你可以添加自己希望的各种功能,比如某种服务,或者定时器之类。

继续阅读

ruby调用执行shell命令的方法

ruby执行shell的方法主要有:

1.Exec方法:

Kernel#exec方法通过调用指定的命令取代当前进程:

值得注意的是,exec方法用echo命令来取代了irb进程从而退出了irb。主要的缺点是,你无法从你的ruby脚本里知道这个命令是成功还是失败。

2.System方法。

Kernel#system方法操作命令同上, 但是它是运行一个子shell来避免覆盖当前进程。如果命令执行成功则返回true,否则返回false。

3.反引号(Backticks,Esc键下面那个键)

这种方法是最普遍的用法了。它也是运行在一个子shell中。

继续阅读

编译ruby2.0.0后gem报openssl错误的解决方法

mac osx下编译安装完ruby2.0.0的时候,使用gem install命令会报:Could not load OpenSSL之类的错误,本以为是openssl没装,于是

还有不行⋯⋯终于执行:

然后make clean,重新编译一下,发现gem又可以正常使用了。

ps.貌似也可以在编译的时候添加下面一个选项:

这样就可以load额外的openssl库,而不使用系统的。

比如编译时用:

不过这两个方法前提都是你自己编译安装了openssl,或者使用brew等工具编译安装过它。

Ruby Rake任务简介(转)

RakeMakeAnt

Rake的意思是Ruby Make,一个用ruby开发的代码构建工具。Rake的英文意思是耙子,一种很朴实的劳动工具。真的是很贴切,Rake正是一个功能强大、勤勤恳恳的劳动工具。

但是,为什么Ruby需要Rake

Ruby代码不需要编译,为什么需要Rake?其实,与其说Rake是一个代码构建工具,不如说Rake是一个任务管理工具,通过Rake我们可以得到两个好处:

  1. 以任务的方式创建和运行脚本
    当然,你可以用脚本来创建每一个你希望自动运行的任务。但是,对于大型的应用来说,你几乎总是需要为数据库迁移(比如Rails中db:migrate任务)、清空缓存、或者代码维护等等编写脚本。对于每一项任务,你可能都需要写若干脚本,这会让你的管理变得复杂。那么,把它们用任务的方式整理到一起,会让管理变得轻松很多。
  2. 追踪和管理任务之间的依赖
    Rake还提供了轻松管理任务之间依赖的方式。比如,“migrate”任务和“schema:dump”任务都依赖于 “connect_to_database”任务,那么在“migrate”任务调用之前,“connect_to_database”任务都会被执行。

在哪里可以获得Rake

Rake的主页是在http://rake.rubyforge.org/,在这里你可以获得Rake的简单介绍,API以及一些有用文档的链接。可以在http://rubyforge.org/frs/?group_id=50获得最新版的Rake,在作者写作时,最新版本是0.7.3。

Rake脚本编写 一个简单脚本

Rake的脚本相当简单,下面用一个例子进行说明。假设你是一个勤劳的家庭型程序员,在周末你打算为你的家人做一些贡献。所以你为自己制定了三个任务:买菜、做饭和洗衣服。打开你的文本编辑器,创建一个名叫rakefile的文件(Rake会在当前路径下寻找名叫Rakefile、rakefile、RakeFile.rb和rakefile.rb的rake文件),并输入如下内容:

打开命令行工具,进入这个文件所在目录,然后运行下面的命令,大致应该类似如下结果:

继续阅读

osx编译ruby-1.9.3-p374

osx下编译编译ruby-1.9.3 p374出了一些问题,本来以为只要加上 --with-gcc=clang就看可以,结果一直报错,错误类似于:

然后找到这个:http://www.ruby-forum.com/topic/2370265

这貌似是个bug,不会用clang编译的人表示不淡定,只能照葫芦画瓢往下弄了:

好了,成功解决,设置PATH,开始使用。

ps.所有工作之前,你可能需要先安装libyaml,可以直接 brew install libyaml,不然gem可能不好用。

ruby写的微博api调用

十一前某天恰好没什么事,就用ruby写了这么一个模块。这个模块可以通过ruby调用weibo open api。今天完善了一下,基本上可用了。代码不多,大概200行。

Github地址: https://github.com/vincenttone/vbo

您可以使用使用git来获取源码:

git clone git://github.com/vincenttone/vbo.git

这次并没有封装成Gem,因为只有一个文件,很容易导入,如果需要gem,请自己打个包,谢谢。test.rb是我测试用的文件,一起上传上来,给大家一个参考。至于详细的使用方法,请参考README.md。

代码中要说的一点是,模块的初始化方法会尝试读取环境变量里的三个变量来填充app_key, app_screct和callback_url,这里如果大家没有这个需要的话,可以删除这段,使用set_app_config方法来进行设置。删除后整个类可以尝试继承basic_object这个类,这样应该可以提高一些性能。

之前似乎见过一次ruby的weibo open api模块,但是不太好用……好吧,虽然我不想承认,但我似乎又重复造轮子了。不管怎样,欢迎交流。