存档

‘ruby’ 分类的存档

Ruby下使用SWIG封装libcurl

2010年9月2日 没有评论

本文通过在ruby下使用SWIG封装libcurl来简要描述如何通过SWIG来扩展ruby。
关于SWIG的入门使用可参见 使用SWIG扩展ruby性能

关于SWIG:
SWIG全称为 Simplified Wrapper and Interface Generator,通过swig可以方便快捷的使用c/c++扩展php, ruby等语言以提高性能或满足其它用途。

关于libcurl:
libcurl是一个著名的http/ftp库,通过libcurl可能轻松通过http/ftp协议访问网络。

流程:

相关文件:
SWIG的封装文件 curl.i

%module curl
%{
#include <curl/curl.h>
%}

/* type definations */
typedef int CURLoption;
typedef int CURLcode;

/* import constants */
%constant int CURL_GLOBAL_ALL = CURL_GLOBAL_ALL;
%constant int CURLOPT_URL = CURLOPT_URL;

/* import functions */
int curl_global_init(long flags);
void curl_global_cleanup();

CURL* curl_easy_init();
void curl_easy_cleanup(CURL* curl);
CURLcode curl_easy_setopt(CURL* curl, CURLoption opt, int v);
CURLcode curl_easy_setopt(CURL* curl, CURLoption opt, const char* v);
CURLcode curl_easy_perform(CURL* curl);

ruby的extconf.rb文件

require 'mkmf'
%w{stdc++ curl}.each do|lib|
	$libs = append_library $libs, lib
end
create_makefile 'curl'

编译build.sh:

#通过curl.i生成封装后的cpp源码
swig -c++ -ruby curl.i &&

#通过extconf.rb生成Makefile
ruby extconf.rb &&

#通过Makefile生成目标扩展
make

测式文件ruby_test.rb

#!/usr/bin/env ruby
require 'curl'
include Curl

url = ARGV[0] || 'http://www.google.com'

p curl_global_init(CURL_GLOBAL_ALL)
p curl =  curl_easy_init()
p curl_easy_setopt(curl, CURLOPT_URL, url)
p curl_easy_perform(curl)
p curl_easy_cleanup(curl)
p curl_global_cleanup()

本文相关的完整源码可在github下载: http://github.com/JiangMiao/ruby_swig_curl_demo
git clone git://github.com/JiangMiao/ruby_swig_curl_demo.git

相关链接:
libcurl
SWIG

分类: 3 ruby/c++ 标签:

Ruby的预定义变量

2010年3月23日 没有评论

一、异常

名称 描述 相当于
$! 捕获的异常 Exception
$@ 异常的backtrace Exception#backtrace

例:

begin
	raise "err msg"
rescue
	p $! # #<RuntimeError: err msg>
	p $@ #["(irb):2:in `irb_binding'", "/usr/local/lib/ruby/1.8/irb/workspace.rb:52:in `irb_binding'", ":0"]
end

二、正则
对于 m=str.match(pattern)

变量 性质 描述 相当于
$& 只读,本地 匹配的项 m[0]
$` 只读,本地 匹配的字符串之前未匹配的部分 m.pre_match
$\’ 只读,本地 匹配的字符串之后未匹配的部分 m.post_match
$+ 只读,本地 最后一个匹配的项 m[m.size-1]
$1,$2 只读,本地 所指定的匹配的项 m[n]
$~ 本地 匹配的结果 m

例:

"start-111-222-333-444-end" =~ /(\d+)-(\d+)-(\d+)-(\d+)/
p $& #"111-222-333-444"
p $` # "start-"
p $' # "-end"
p $+ # "444"
p $1 # "111"
p $2 # "222"
p $~[3] # "333"

三、IO/String

描述 默认 说明
$_ gets,readline最后读入的行
$F $_.split 仅当选项-a为真时
$/ “\n” 用于gets,readline等分割符
$\ nil print与IO.write的分割符
$, nil Array#join的分割符
$; nil String#split的分割符
$. ARGF.lineno
$< ARGF
$* ARGV
$> $defout
$defout print与printf的输出变量,缺省为$stdio
$stdin 当前标准输入 缺省 STDIN
$stdout 当前标准输出 缺省 STDOUT
$stderr 当前标准错误输出 缺省 STDERR

四、进程

名称 描述
$0 当前ruby程序名
$$ Process.pid
$? 最后执行的外部程序的返回状态

四、其它

名称 描述
$: $LOAD_PATH
$” 已require的module,用于避免二次载入
$DEBUG 是否为DEBUG状态, -d –debug开启则为真
$FILENAME $<.filename
$SAFE 安全等级
$VERBOSE verbose选项是开启则为真
$-O $/
$-a -a选项开启则为真
$-d $DEBUG
$-F $;
$-I $:
$-l -lis选项开启则为真
$-p -pis选项开启则为真

分类: 1 ruby/基础, ruby, 编程 标签:

如何编写RubyGems

2010年3月21日 没有评论

目标:通过本文章学习并编写一个gem ‘hello’

一、认识RubyGems
1、什么是RubyGems
RubyGems是ruby下的包管理系统。最著名gem的当属Rails

2、gem的基本文件布局

文件名 类别 描述
gemspec 文件 gem的规范说明。
lib 文件夹 用于lib文件的存放
bin 文件夹 可执行文件
ext 文件夹 c/c++源文件
tests 文件夹 单元测试文件

3、gemspec文件规范常用项

名称 类别 缺省 描述
*name String gem名称
*version String 版本号
*date Time Time.now Gem创建日期
*platform String Gem::Platform::Ruby gems所使用的平台
*summary String gem描述
*require_paths Array ["lib"] 用于require调用时的默认路径
files Array gems所包含的文件

以上为关键的几个选项,其中打*号的为必须的项,若要添加作者,可执行文件等选项可参见Gem规范

3、编译
gem build gemspec文件

4、安装
gem install 生成的gem

二、编写最简gem hello
1、创建文件与文件夹
hello/hello.gemspec
hello/lib/hello.rb

2、编写 hello.gemspec

Gem::Specification.new do |s|
	s.name = 'hello'
	s.version = '0.1.0'
	s.summary = 'hello gems'
	s.files = ["lib/hello.rb"]
end

3、编写 lib/hello.rb

def hello
	"HELLO"
end

4、编译

gem build hello.gemspec

5、安装

gem install hello

6、测试

require 'rubygems'
require 'hello'
puts hello

—-
输出HELLO 测试成功

三、相关链接
1、RubyGems官方网站
2、Rubyforge
2、Gem规范
3、本文的hello gem源码

分类: 1 ruby/基础, ruby, 编程 标签:

Btk 0.1.0

2009年11月25日 没有评论

Btk 基于 Ruby GTK2 的扩展,大大方便ruby下的gui。
安装:gem install btk
主页:http://btk.rubyforge.org/

Hello World:

require 'rubygems'
require 'btk'

# w will call border_width= or set_border_width with parameter 10
Btk.Window :border_width=>10 do|w|

        #alias of signal_connect('delete_event')
        w.sig_delete_event do
                puts "delete event occurred"
                false
        end

        #alias of signal_connect('destroy')
        w.sig_destroy do
                puts "destroy event occurred"
                Gtk.main_quit
        end

        # Button will add to w automatically
        w.Button "Hello World" do|btn|
                btn.sig_clicked do
                        puts "Hello World"
                end
        end
        w.show_all
end
Gtk.main

 

分类: 4 rubygems, 编程 标签:

从rails回到了php

2009年2月12日 2 条评论

从rails回来,重新用起了php,起因还是由于rails render一个63k的view要多花去10ms,这个view就一个erb fragment缓存,,即由原来每个响应20ms下降到30ms,降低了足足50%,很受伤,后然尝试使用merb,但merb不太习惯,正值ruby1.9.1,Rails2.3发页,又尝试ruby1.9.1,可惜很多gems都未能完善,fcgi,mongrel都无法工作,只能用回了1.8.7。最后无奈之下用回了php。用php重写了所有代码后,一模一样的操作那个63k的页面只需10ms。 

但rails给我的启发是巨大的,现在我的目录结构也仿rails, 如app,config,public,log,tmp等。我甚至写了个Rakefile用来管理文件的常用操作,使用了ruby的2个月。学到了不少。ruby我还会继续用他,作为我的刀,希望ruby越来越好,早一天让我从php又回到了ruby。

分类: php, ruby, 编程 标签:

ruby稳定版已更新为1.9.1-p0

2009年2月10日 没有评论

今天发现stable version已从1.8.7升至为1.9.1-p0。一会测试一下兼容性和性能的提升。

相关链接
Ruby官方网站

–2009-02-10补充–
到正式可以用至少还要1个月,许许多多gems都还未能兼容1.9.1。部份版本已出了新版本,但都还在github中。
ruby的脚步太快, 追起来有点吃力,暂时驻足观望一阵。

分类: 5 ruby/其它, ruby, 编程 标签:

rb_yield让ruby/c++更加紧密

2009年1月26日 没有评论

用c++写ruby模块提升性能效果显著一文让我初尝甜头,但未免连render都用c++也太得不尝失。自从使用了rb_yield,一切问题迎刃而解。

如代码

class Test
  def foo
    yield
  end
end

相对应的c++代码则为

#include "ruby.h"
typedef VALUE(*RUBY_FUNC)(...);
extern "C" VALUE t_foo(VALUE self)
{
  //do something by c++
  rb_yield();
  //do something by c++
}
VALUE cTest = rb_define_class("Test",rb_cObject);
rb_define_method(cTest,"foo",(RUBY_FUNC)t_foo,1);

非常的方便有效。

分类: 3 ruby/c++, 编程 标签:

ruby升到1.8.7,性能提升到我吐血。

2009年1月26日 没有评论

早听说debian/ubuntu的1.8.6是debug模式,比正常的慢50%,一直没在意,反正是测试服务器不缺这点时间。

前几篇日志提到的600个节点的树递归生成时间与render耗时太长,要近200ms,c++render虽然快但不实用,于是今重写了扩展对erb进行yield,但最终只能优化到70ms(3ms树生成+70ms render),最后发现即使什么都不作进行600次link_to操作也要花掉60-80ms。随抱着试试的心态升到了1.8.7
升级后发现目录也改成像freebsd的/usr/local/…的样子不太熟悉。然后安装gem又折腾了一阵。最后怀着激动的心情安装好一试,!只要20-40ms!又试了试其它页面,原本要花0-6ms的页面全都稳定得变为0-1ms。太爽了!!!

边守岁边测试,看到这满意的结果,能安心的睡个好觉了。

越来越中意ruby了

分类: 5 ruby/其它, ruby, 编程 标签:

用c++写ruby模块提升性能效果显著

2009年1月17日 1 条评论
对于生成600项item的树型目录。
纯ruby代码大约200ms
包括rails初始化(0-6ms),mysql查询(0-2ms),树型生成(20-30ms),递归render,其它。

经过c++重写后,全部只需10ms。实在太爽啦。
如果那递归render都用c++代替,那感觉是用C++写网页,而不是用ruby写网页,利用不到rails提供的很多特性。但递归render 600项实在耗时,鱼和熊掌不能兼得,得另想法子。

分类: 3 ruby/c++, ruby, 编程 标签:

使用SWIG扩展ruby性能

2009年1月16日 没有评论
  在使用ruby/rails的过程中,确实发现有时性能不尽人意,如生成一个拥有600项的item的3层树形结构目录要花去20ms,为提高性能在学习用c/c++写ruby模块的过程中,认识了swig,rubyInline等一系列帮助编写c/c++来提升ruby性能的辅助工具。
  rubyInline用于内嵌c/c++程序,简单快捷,
  swig则帮助我们更容易地用c/c++写出独立的ruby模块。 

swig的入门使用方法
目标:用swig/c++编写一个ruby模块Test,并提供add方法作加法运算。
相关文件:

  • test.i 接口
  • test.h 头文件
  • test.cxx 函数实现
  • extconf.rb 用于生成makefile
  • (自动)test_wrap.cxx swig生成的test封装
  • (自动)Makefile Makefile文件由ruby extconf.rb得到
  • (自动)test.so ruby模块 由make得到

1、建立接口文件test.i

%module test
%{
//包含头文件
#include "test.h"
%}
//接口add
int add(int,int);

2、编写wrap文件

swig -c++ -ruby test.i

得到test封装文件 test_wrap.cxx

3、编写test.h与test.cxx

//test.h
#ifndef _TEST_TEST_H
#define _TEST_TEST_H
extern int add(int,int);
#endif
//test.cxx
#include "test.h"
int add(int left,int right)
{
        return left+right;
}

4、编写extconf.rb用于快速生成makefile

require 'mkmf'

dir_config 'test'
#stdc++库,add函数未用到
$libs = append_library $libs,'stdc++'
create_makefile 'test'

运行 ruby extconf.rb 得到 Makefile 文件

5、生成test模块
运行 make 得到模块 test.so

6、测试

irb
irb(main):001:0> require 'test'
=> true
irb(main):002:0> Test.add 3,4
=> 7
irb(main):003:0> Test.add 3333333333333333333333,44444444444444444
TypeError: Expected argument 0 of type int, but got Bignum 3333333333333333333333
        in SWIG method 'add'
        from (irb):3:in `add'
        from (irb):3
        from :0
irb(main):004:0>

测试成功

7、swig
swig支持很多c++的高级特性来编写ruby的模块,如类,继承,重载,模板,stl等。

8、相关链接

9、备注
本文的add函数过于简单,对比ruby 3+4性能不升反降。

分类: 3 ruby/c++, 编程 标签: