作者retsamsu (haha)
看板Ruby
标题[分享] 以前写的关於Ruby的文章
时间Fri May 19 17:24:29 2006
http://blog.xuite.net/retsamsu/diary/35334603
不过这个blog很久没更新了(也没空哈哈)
之前作一些project的心得,大家勉强看看吧~
使用ruby也有一点时间了,最近大改一个之前写的程式,发现有很多的心得,
想跟之前的心得合起来记在这,供日後的参考。
ruby是一个日本人Yukihiro Matsumoto(matz)开发的Object-Oriented Script
Language,在新版的RPGMaker里可以使用ruby写脚本。如果你已经会了perl,
shell scripts,java等语言,这个东西将很容易上手(我的第一个程式就是改厂商的
perl程式成ruby版本,至於为什麽要改,大概是主管对perl 的奇怪偏见吧:))。
以下是使用ruby 1.8(on fedora core 3)来写作的心得。
一般来说跟perl的写法几乎一模一样,只有一些地方不一样(我碰到的):
1. 变数前面一般来说不用加$,因为加$是global变数。
hello # local variable
$hello2 # global variable
@hello3 # instance variable,可从其包含该值得object得到该值
HELLO4 # constant variable
2. 字串里秀变数值,或是要把值从变数拿出来时,就在变数上加上#{}就可以
把值拿出来了。
puts "hello: #{var_1}\n" #印出含var_1的字串
3. 叙述句结束也不用加;号。
4. if-then-else-end,for,loop,更加的灵活。
2000.times {
do_something
} # 做2000次 do_something
for i in collection # collection可以是一堆数字,一堆array...
...
end
5. try-catch exception处理。使用rescue,raise等解决。
begin
f = File.new("abc")
...
rescue
puts "files abc can not be created.\n"
end
基本上我碰到修改与perl不同的大概就是这些。接下来就是实作程式时得到的一
些心得。我把原来的perl程式改写成了一只multi-thread的daemon,碰到了不少
问题,以下就是我的心得。
1. ruby连结mysql:里面并没内建连结mysql的函式,要去安装ruby-mysql。
使用方法也很简单,如下所示。
require "mysql"
...
my = Mysql::new(mysqldbhost, mysqldbuser, mysqldbpasswd, mysqldbname)
res = my.query(sql_query_language)
res.each do |row|
col1 = row[0]
col2 = row[1]
...
end
基本上我用的大部分是传回一个hash,然後再根据名称找值。
2. 建立一个daemon:用fork,loop就可以完成。加一个pid比较好控制。使用-kill
只会把之前的process砍掉。
# 外部呼叫砍掉之前的process
if ARGV[0] == "-kill" then
# pidfile存在,先把之前的process砍掉
if File.exists(pidfile) then
f = File.open(pidfile)
previus_pid = f.readlines()[0].to_i
f.close
Process.kill("SIGHUP", previus_pid)
end
exit
end
# pidfile存在,先把之前的process砍掉
if File.exists(pidfile) then
f = File.open(pidfile)
previus_pid = f.readlines()[0].to_i
f.close
Process.kill("SIGHUP", previus_pid)
end
# 写新的pid到档案里
f = File.open(pidfile, "w")
f.write("#{Process.pid}\n")
f.close
#主程式daemon开始
fork do
loop do
daemon_main_procedure
end
end
exit
3. Thread的使用:ruby提供一系列的Thread函式,不过因为主程式没有等其他
thread做完的特性,老是主程式马上结束了,但是其他thread没做完(其他thread
作一些IO与存取资料库的动作)。一开始有想要用join,来等其他的thread,但是
被发现这样其实不太像thread(一个一个做),结果使用array与while loop就可
以达成。
to_do_list = ""
...
Thread.new(){|t|
to_do_list.push(t)
do_thread_thing
to_do_list.pop(t)
}
while to_do_list.length!=0
# spin lock
end
4. 使用pop3:因为我的程式有去读信的动作,因此使用此函式,不过因为後来觉得
如果使用者很多的时候pop3 server会爆掉,然後原来的程式在consistence上会有
很大的问题,就用其他的方法了。
require 'net/pop'
...
pop = Net::POP3.new(pop3server)
pop.start(pop3user, pop3passwd) do |pop|
msg = pop.mails[0]
header = msg.header
body = msg.gsub("\r\n\r\n") # 两个enter後为内文
...
pop.mails[0].delete # 砍掉mail
end
pop.finish
...
5. 因为之前4的问题,因此改采直接从本地端的mailbox(/var/mail/username)来读信。
好加在ruby有solution,差点又要回去找perl了:)
这样一来也比较快,而且不会用到pop3 server,也减少被try站的机会。
require 'mailread'
...
mailbox = File.open("/var/mail/username")
until (m = Mail.new(mailbox)).header.empty?
header = m. header
body = m.body
end
File.truncate("/var/mail/username") # 砍掉mail
最後,说一下这个ruby其实还蛮好用的,不过文件总是很乱,也没什麽固定的
(我觉得的),不过ruby-doc mailling list有人发起重新写文件的计画,希望能
写的更好,让programmer查的更方便。
Posted by retsamsu at 11:18.Sep 3, 2005
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.113.209.4
1F:推 fayhong:没错... ruby 文件很乱....XDDD 05/19 18:34
※ 编辑: retsamsu 来自: 140.113.209.4 (05/19 22:07)
2F:推 retsamsu:修改一下标题符合版规 05/19 22:07
3F:推 K60258:推 好 10/31 00:53
※ 编辑: retsamsu 来自: 140.113.209.21 (06/25 02:44)