Ruby 语言 思想驱动生活

April 28, 2007

MediaWiki的url rewrite

Filed under: 技术 — liubin @ 23:01

因为使用虚拟服务器,不能修改apache的配置文件,一般的url rewrite都需要.htaccess文件。
mediawiki的话,简单的步骤如下
1. 在LocalSettings.php中设置$wgArticlePath = “/wiki/$1″;
2.在wiki的根目录中放置含有如下内容的.htaccess文件

  1. RewriteEngine on
  2. # 取消下一行的注释#号,如果你期望输入主域名oracle.nanshapo.com/时直接转到oracle.nanshapo.com/wiki/Main_Page
  3. # RewriteRule ^/$ /wiki/Main_Page [R]
  4. RewriteRule ^wiki/(.*)$ /index.php?title=$1 [L,QSA]

可以访问oracle.nanshapo.com来看看

April 26, 2007

下载youtube的视频并转换为mp3

Filed under: 垃圾 — liubin @ 21:01

1.下载
不用自己费力分析原文件什么的了,直接有很多网站都提供了这个方便的工具,比如
http://kej.tw/flvretriever/
在输入框输入youtube的网址,按retrieve me按钮,下面就会出现下载的链接:
save as a new file and then you can rename it as a .flv file

2.将flv转换为mp3
需要工具:
下载软件,地址(此软件也可播放flv文件):http://download.rivavx.de/RivaEncoderSetup.exe
安装之后有一个播放器,一个编码器。
打开编码器,input video 选择刚才下载的flv文件,output 的文件扩展名改为mp3,最后就会保存为mp3文件了。
按下encoder 按钮,这时候界面都会变灰,转换完之后,界面会恢复的。
这个工具应该支持将flv文件转换为mp3,wmv,mpg等。

April 11, 2007

日本Ruby会议2007

Filed under: Ruby — liubin @ 21:15

主题演讲:

  • Matz
  • Dave Thomas
  • 发表者

  • ささだ こういち
  • 卜部 昌平
  • 青木 峰郎
  • Charles Nutter
  • Thomas Enebo
  • 立石 孝彰
  • 桑田 誠
  • arton
  • 朴 芝印
  • Tim Bray
  • 関 将俊
  • 後藤 謙太郎(ごとけん)
  • 高井 直人
  • John Mettraux
  • 篠原 俊一
  • 加藤 究
  • 永井 秀利
  • 武藤 昌夫 (むとう まさお)
  • nyasu
  • 藤本 尚邦
  • 舘野 祐一(secondlife)
  • 大林一平(ohai)
  • 原悠(yhara)
  • 須藤 功平
  • えと こういちろう
  • 难道那个姓朴的是韩国人。

    April 9, 2007

    Filed under: 垃圾 — liubin @ 21:25

    最近一个星期,已经下了三次雨了。
    每天晚上淅淅沥沥的,早上路上都是落下的花瓣。
    一冬天都没见到雪了,也没见到冰,除了麦当劳的可乐。
    最近机会每个星期要吃2,3次麦当劳,每次4个汉堡一杯可乐。

    冠军杯我仁平了,我魔输了。

    原来冯还真有ping这个读音。今天学习到了。

    昨天买了个x60,小是小,不过太小了。比原来的那个15.4宽屏的小多了。
    以后可以用大的看电视,现在电脑对我来说快变成电视了。
    发现ThinkPad果然是越来越不行了。

    April 6, 2007

    redMine

    Filed under: Rails — liubin @ 20:20

    基于rails的项目管理工具。
    进到它的demo程序里看了一下,还是非常不错的,不管是功能上还是界面上,都是比较好的选择。

    主要功能包括:
    支持多个项目
    灵活的基于角色的访问控制
    灵活的issue追踪功能
    甘特图和日历功能
    News, documents & files 管理
    反馈,邮件通知功能
    issue,项目,用户可以客户化Custom
    SVN 代码库浏览功能
    多LDAP认证支持
    用户可以自己注册,然后通过mail激活
    多语言支持
    多数据库支持。

    推荐大家使用。主页是http://www.redmine.org/

    这是甘特图的例子:
    gantt

    April 5, 2007

    【翻译】YARV源码读解

    Filed under: Ruby — liubin @ 22:25

    YARV源代码解读,原作者hzkr,发表于其blog上。http://d.hatena.ne.jp/hzkr/19000101
    共15回,历时近5个月(2006/10/27~2007/04/02)完成的。RHG有人在翻译成英文和中文的,YARV的源码阅读还没有人写过(个人所知范围内)。2007年圣诞的时候将要发布的Ruby1.9将会集成YARV(那时候应该不再算是another了吧)

    共15回,以下是翻译计划(和实际完成情况),共计需要两个月左右,挺长的啊。
    由于本人水平比较差,如果看的实在不通顺什么的,还请不要太见怪了。
    第一回(2007-4-5,已发)
    第二回
    第三回
    第四回
    第五回
    第六回
    第七回
    第八回
    第九回
    第十回
    第十一回
    第十二回
    第十三回
    第十四回
    第十五回

    【翻译】YARV源码读解(1)

    Filed under: Ruby — liubin @ 22:12

    YARV是面向对象脚本语言Ruby的一个实现。和普通的Ruby不一样,它的特点是把脚本转换成虚拟机上的bytecode,能高速执行。
    最近,Parrot,CLR,JavaVM等基于虚拟机的编程语言好像比较热门。想着能深入了解某一种就好了,于是选择了YARV。另外,我连10行的Ruby都没编过,在学习Yarv的同时,也能顺便学习一下Ruby。

    1.资料
    现在时点(2006/11/)Yarv的最新版本是0.4.1。为什么没有从cvs下来最新的代码呢?因为手里没有bison(GNU版的YACC),所以就偷点懒了。
    可以参考的网站

    YARV: Yet Another Ruby VM
    Yarv的老家。源代码的下载,和Yarv的架构设计文档等。
    YARV Maniacs
    Rubyist Magazie的连载文章,介绍Yarv的。Yarv的作者写的,介绍了在源代码上如何实装等的一系列文章。
    Ruby源代码完全解说
    青木峰郎写的Ruby源代码解读的书。除了Yarv核心以外,其它的Ruby等内容,可以参考这本书

    main @ main.c
    main函数中初始化完了后,就可是执行代码了。这里看一下这之前的一些流程。先来看一下main函数。Ruby/Yarv就是从这里开始执行的。去掉依存于环境的#ifdef等先不管,简单的main函数就是这个样子:

    1. int
    2. main(int argc, char **argv, char **envp)
    3. {
    4.     {
    5.         RUBY_INIT_STACK ruby_init();
    6.         ruby_options(argc, argv);
    7.         ruby_run();
    8.     }
    9.     return 0;
    10. }

    最初的RUBY_INIT_STACK是GC所需要的,记住stack开始位置的宏。所做的事情主要的就是把stack的开始地址赋给变量rb_gc_stack_start(IA64系统好像是别的变量)。宏定义如下:

    1. #define RUBY_INIT_STACK \
    2.     VALUE variable_in_this_stack_frame; \
    3.     ruby_init_stack(&variable_in_this_stack_frame);

    这样,在stack声明了一个变量variable_in_this_stack_frame,并把把这个变量的地址传给了ruby_init_stack 。 ruby_init_stack中包括对stack的增长方向检查等稍稍复杂的工作,抛开这些和当前讨论有关的内容简单来说如下面这样:

    1. void ruby_init_stack(VALUE *addr)
    2. {
    3.   ... 略 ...
    4.     rb_gc_stack_start = addr;
    5.   ... 略 ...
    6. }

    像上面那样。这段代码(变量),可能在之后会被GC不停的访问,今天就不深入研究了。

    接着,顺序调用下面3个函数

  • ruby_init (处理本体和内置模块的初始化)
  • ruby_options (命令行传过来的参数的解析)
  • ruby_run (脚本的执行)
  • 好了,接着顺次地进行读解下面的内容
    ruby_init @ eval.c
    下面是初始化函数ruby_init 的主要部分的摘要:

    1. void
    2. ruby_init()
    3. {
    4.   ... 略 ...
    5.     Init_yarv();
    6.     Init_stack((void *)&state);
    7.     Init_heap();
    8.  
    9.     PUSH_TAG(PROT_NONE);
    10.     if ((state = EXEC_TAG()) == 0) {
    11.     rb_call_inits();
    12.     ruby_prog_init();
    13.     ALLOW_INTS;
    14.     }
    15.     POP_TAG_INIT();
    16.   ... 略 ...
    17. }

    Init_yarv!终于见到YARV了!
    在继续之前,先看一下那句后面的if语句。这个if语句对第一次看Ruby源代码的人来说应该像迷一样吧。

    1. PUSH_TAG(PROT_NONE);
    2.     if ((state = EXEC_TAG()) == 0) {
    3.       ...
    4.     }
    5.     POP_TAG_INIT();

    嗯,再看看EXEC_TAG的定义。

    1. #define TH_EXEC_TAG() \
    2.   (FLUSH_REGISTER_WINDOWS, ruby_setjmp(_th->tag->buf))
    3.  
    4. #define EXEC_TAG() \
    5.   TH_EXEC_TAG()

    ruby_setjmp是setjmp或_setjmp的#define定义。这里好像是调用了setjmp。Setjmp最开始的时候返回0,里面如果有logjmp的话,则返回非0的值。

    1. if ((state = EXEC_TAG()) == 0) { // ※
    2.       // 最初EXEC_TAG==setjmp返回0,所以代码执行到这里
    3.         // 如果这附近出错的话,里面会调用longjmp来进行跳转
    4.         // 所以在跳向※的时候返回非0值。
    5.       ...
    6.     }
    7.     // 处理将转向到这里

    这里的处理有点像begin~rescue 的处理过程。不过如果考虑的例外的话可能就要费很大精力了,所以先不过if (…) 这句,继续看下面的代码。
    (※稍微看了一下 Ruby Hacking Guide,好像像***_TAG这样的jump tag在Ruby进行评价(eval)的时候用了很多。Yarv怎么样还不知道,如果使用到了,到那时候再调查。)
    接着往下,ruby_init调用的初始化函数中,和yarv有关的只有两个,最初被调用的Init_yarv和在rb_call_init中被调用的Init_yarvcore。
    - Init_yarv
    - rb_call_inits
         – …
         – Init_yarvcore
         – …
    其它的普通的Ruby内部对象的处理等因为和Yarv没什么关系,都可以忽略不看。

    Init_yarv @ yarvcore.c
    第一个初始化函数是 Init_yarv:

    1. void
    2. Init_yarv(void)
    3. {
    4.     /* initialize main thread */
    5.     yarv_vm_t *vm = ALLOC(yarv_vm_t);
    6.     yarv_thread_t *th = ALLOC(yarv_thread_t);
    7.  
    8.     vm_init2(vm);
    9.     theYarvVM = vm;
    10.  
    11.     th_init2(th);
    12.     th->vm = vm;
    13.     yarv_set_current_running_thread_raw(th);
    14. }

    上面的代码先初始化了两个构造体。一个是表示yarv虚拟机构造体(yarv_vm_t),另一个是表示线程的构造体(yarv_thread_t)。vm_init2只是把memroy进行了zeroclear(使用了MEMZERO()函数),th_init2里面应该是frame的stack的做成,但是还没有看到Yarv的执行部分,具体是什么意思也不太清楚。等后面到了线程构造的部分在来检查吧。
    先记着生成了这两个构造体就行了。两个局部标量初始化之后,会把虚拟机变量赋给theYarvVM,这个值可以用宏GET_VM()获得它的值。线程构造体变量th在yarv_set_current_running_thread_raw函数里会赋给变量yarvCurrentThread,这个值可以用宏GET_THREAD()获得。

    Init_yarvcore @ yarvcore.c
    目前的yarv是作为ruby library来工作的(现在的yarv已经合并到Ruby里了),这个函数定义了Ruby的扩展库模块。

    1. mYarvCore = rb_define_module("YARVCore");
    2.     rb_define_const(mYarvCore, "VERSION",
    3.                     rb_str_new2(yarv_version));
    4.     ... 略 ...

    先不管这些,知道是一个Library就行了。途中会看到

    1. // make vm
    2.     /* create main thread */

    这样的注释,开始时候会感到疑惑,难道刚才没有建立吗vm之类的变量吗?保险起见,仔细看了一下make vm以后的内容。

    1. /* create vm object */
    2.     VALUE vmval = vm_alloc(cYarvVM);
    3.     yarv_vm_t *vm;
    4.     yarv_thread_t *th;
    5.     vm = theYarvVM;
    6.  
    7.     xfree(RDATA(vmval)->data);
    8.     RDATA(vmval)->data = vm;
    9.     vm->self = vmval;

    vm_alloc(cYarvVM) 方法创建了YarvVM类的实力(实际上是构造体变量),再把刚才做成的theYarvVM赋给vm,vmval也会赋给vm构造体的属性里。可以看出,theYarvVM是YARV内部使用的虚拟机变量。这里做成的vmval变量,是一个能在ruby脚本中能使用的包装对象(VALUE类型)。
    继续往下,到了注释create main thread 的地方了

    1. /* create main thread */
    2.     vm->main_thread_val = yarv_thread_alloc(cYarvThread);
    3.     GetThreadPtr(vm->main_thread_val, th);
    4.  
    5.     vm->main_thread = th;
    6.     vm->running_thread = th;
    7.     GET_THREAD()->vm = vm;
    8.     thread_free(GET_THREAD());
    9.     th->vm = vm;
    10.     yarv_set_current_running_thread(th);

    跟上面的一样yarv_thread_alloc(cYarvThread)方法里创建了YarvThread的一个实例。
    - yarv_thread_alloc
         – thread_alloc
         – thread_init
             – th_init
    yarv_thread_alloc里面又用th_init建立了一个thread类型的构造体,然后在后面,又用thread_free把刚才做成的thread 变量(GET_THREAD())给释放了,又在set_current_running_thread里面把刚才建立的变量th赋给了yarvCurrentThread。
    为什么这样做呢?因为Init_yarvcore有可能被反复地调用,所以在调用之前就把前面的thread给销毁了。但是这样的话为什么要在Init_yarv要先做成一个thread呢?目前还不明白,留作以后的课题吧。
    ruby_option @ eval.c
    初期化完了之后,就是对命令行参数的解析了,也没有什么特别值得一提的东西,就略过了。
    ruby_run @ eval.c
    最后,在main函数里调用了ruby_run函数。在ruby_run中调用了很多函数,但是主要的流程还是如下面所列的那样。
    - main
        - ruby_run
             – ruby_exec
                 – ruby_exec_internal
                     – yarvcore_eval_parsed @ yarvcore.c
    终于到了yarvcore!

    1. VALUE
    2. yarvcore_eval_parsed(NODE *node, VALUE file)
    3. {
    4.     VALUE iseq = th_compile_from_node(GET_THREAD(), node,
    5.                                       file);
    6.     return yarvcore_eval_iseq(iseq);
    7. }

    参数node是已经解析完的ruby语法书(syntax tree ,日语为构文木),参数file是ruby脚本源文件。这个函数比较容易读,主要是把语法树编译(转换)成iseq(Instruction Sequence,指令序列?),然后交给yarvcore_eval_iseq去真正的执行。

    总结
    下周,读compile和eval哪个比较好呢?还是先看data检查比较好呢?

    接下来将阅读
    PUSH_TAG, EXEC_TAG 等tag jump的实装
    th_init2 : Ruby的做成一个线程的函数的详细内容
    Init_yarv 做成的线程的意义

    *中间有段注释老是乱码(IE有,FireFox没有),不知道是什么问题?乱码部分内容如下:
       if ((state = EXEC_TAG()) == 0) { // ※
         // 最初EXEC_TAG==setjmp返回0,所以代码执行到这里 …
         // 如果这附近出错的话,里面会调用longjmp来进行跳转
         // 所以在跳向※的时候返回非0值。
       …
       }
       // 处理将转向到这里

    April 4, 2007

    冯巩的拼音==pinggong

    Filed under: 技术 — liubin @ 23:17

    因为一直在用非中文系统,输入韩语只能用微软拼音。最近google输入法挺入人视线,就下载一个试试看。本人对Google不太感冒
    第一眼感觉速度挺快,有点类似紫光。很遗憾紫光在非中文下乱码,不能用。
    不过,安装的时候默认的时候是选中安装Google toolbar的。
    刚才输入toolbar的时候,发现还有英文联想,当我输入到toolb的时候,出现了toolbox这个提示,再输入a,toolbox就显示出来了。
    不过,发现构造体竟然没有,只有构造题,这个莫名其妙的词语。当然,第二次输入的时候就有了,虽然被排在了第二个。
    输入第二也比较简单,dier就可以了,不会变成爹了。
    总之还不错,速度挺快。
    下载地址:http://tools.google.com/pinyin/
    晚上回家之后,发现了一个更热闹的新闻,就是说google词库抄袭了sogou的词库。
    说是sogou开发人员的名字在Google输入法里也是默认有的。
    具体可以看:这里这里
    这其中最搞笑的是,冯巩的拼音直接输入fenggong使不能出现的,而输入pinggong则第一个显示出来了。

    Telelogic Tau3.0使用感受

    Filed under: 技术 — liubin @ 23:12

    上个月有机会用了一下Telelogic 的Tau3.0,说一下感觉。

    Telelogic Tau3.0是Telelogic的支持uml2.0的建模工具,同时提供了模型验证(Model Verifier),代码生成(code generator)。这是个欧洲公司,据说已经有14年的业内经验了。那个时候uml的版本还是负的2.0吧。

    1.Uml建模
    比较容易使用。
    最重要的是,它对模型的要求比较严格。比如序列图中的对象或者消息,必须是已经定义的。否则会出错的。这样严格应该是为了代码生成和模型验证吧。
    Tau3.0有一种特殊的图,叫做text图,一般来说是一个类的方法的实现。在text 图里面有一个action symbol,就是一个类似输入框的东西,在里面可以写代码。但是代码不是要用tau的语言来写的,不是c,也不是java。在状态机图中,也可以画action symbol。另外。还有一个图形元素叫做text symbol,也可以写代码。
    为了及早检查出错误,tau有自动和手动check功能。跟ide里类似,比如函数名没定义,变量没定义等等。手动检查,可以在要检查的元素上按右键选择,或者使用快捷键f8。
    好像没有timing图支持。

    2.模型验证
    这个应该是很多工具不具备的。
    就是在uml模型上执行。要想进行模型验证和代码生成,至少需要类图和状态机图。序列图活动图,和用例图不被使用,其他图根据需要有可能被使用。需要的图和代码生成一样。
    说是验证,实际上就是把模型生成可执行代码,执行。在uml模型上,能看到执行的过程等。基本的debug机能都有,step in ,step out 等,还有break point ,代码覆盖率统计的。比较不错,第一次看到时惊奇了一把。

    3.代码生成
    能生成c,c++,java代码。并且能编译成可执行文件。
    还能生成telelogic的面向嵌入式系统的agile c。
    这次我做的是生成agile c和c代码。
    基本上生成的代码不可读,不可调试,里面很多宏定义,在uml建模时候的变量名,生成之后也变得乱七八糟的了。
    我们设计主要集中在业务领域,通过signal和外部联系。当然内部也有signal通信了。
    主函数是uml kernel提供的,不停的去检测外部环境进来的signal。默认的性能比较差,什么都不干cpu就在95%以上。

    4.其他
    其它也提供了一些不错的东西,比如TestingProfile,启用了这个插件,就能建立各种test case 了。而且test case 是基于序列图和状态图的,基本也不用编码,只需要画图。一组test case 建立在test context之中,这个context执行后,会生成一个xml格式的报告。

    April 3, 2007

    rails1.2和rails1.1哪个快些?

    Filed under: Rails — liubin @ 21:46

    rails1.2和rails1.1哪个快些?
    Stephan Kaes前天发布了Railsbench 0.9.2
    这个事来测试rails应用程序的性能的软件。
    最新版才有了对post数据的测试。
    同时,作者也发布了一个测试报告,最后的结论中,有一条就是1.2的速度要比1.1慢一半。
    不知道yarv能不能解决这个问题呢?
    等到今年圣诞节就该知道了。

    Powered by WordPress