顯示具有 Ruby 標籤的文章。 顯示所有文章
顯示具有 Ruby 標籤的文章。 顯示所有文章

2007/07/06

讀完 Ruby Programming

無法查看此摘要。請 按這裡查看文章。

2007/06/13

JRuby 1.0 - pure-Java implementation of Ruby

距離上次寫 Ruby 學習手札好像距離很長一段時間了orz

最近無聊亂繞多看了一些網誌,發現 JRuby 這玩意。原來這是個以 JVM 作為平台來實現 Ruby 語言的直譯器,實在有趣。剛好被我發現的時候出了眾所期待的 1.0 版本,對我來說也是剛好,馬上下載安裝。

JRuby 官網:http://jruby.codehaus.org/

如果是 Windows 環境,下載區內有個 jruby-bin-1.0.zip 的就是了。存到本機後隨意解壓,例如 C:\jruby。注意因為這是以 JVM 為平台的,所以 Sun 的 JRE 也要安裝,因為我個人就讀科系的關係,剛好有安裝 JavaSE 6 JDK。接著只要設定環境變數 PATH 和 JAVA_HOME 就搞定了。PATH 加上剛才解壓後的目錄內的 bin 目錄位置 (本例是 C:\jruby\bin),JAVA_HOME 就比較容易,直接找到 JRE/JDK 的安裝目錄就可以了,不需要特別指到 bin 目錄 (像我是 C:\jdk)。這樣安裝就完成了。

到底怎麼用呢?很簡單,打開命令提示字元,打入 jruby -v 看看,假如出現一行版本資訊 (ex: ruby 1.8.5 (2007-06-07 rev 3841) [x86-jruby1.0]) 那就成功啦,如沒有請檢查環境變數設定是否正確。接著便可以打開文字編輯器來寫 Ruby 了。

JRuby 吸引我的其中一個功能是它已經可以使用 Java 廣大的套件,例如 Swing (javax.swing) 套件,這根本是如虎添翼啊。我對 Ruby 的基本還不是相當熟,但是我對 Java 的熟練肯定比 Ruby 要來的高 (廢話,學科有當掉壓力啊XD 雖然我的成績沒有什麼危機w)。之前熟悉的一些套件碼就可以搬過來讓 Ruby 用用,實在不錯。所以就是改用 Ruby 寫 Java 程式的感覺,我想這樣的學習方式也不錯啦 XD



試寫 JRuby,第一行首先要引入 Java 操作套件庫,然就就可以跟 Java 接軌,這感覺真奇妙。能用我熟悉的 JOptionPane 作使用者交互介面還真好玩 :-)

以上程式碼主要使用 java.util.GregorianCalendar 和 JOptionPane.showConfirmDialog 做一些操作,以使用者輸入的年紀回算出生西元年。題外 include_class 不能像 Java 的 import 使用星號真是囧啊,常常忘記某個類別屬於那個 Package,還得到 API 查查。

喔,JRuby 跟 Ruby 一樣還是屬於 Scripting Language,雖然 JRuby 1.0 說有 JIT Compile 以提升執行速度,不過我沒看到什麼 class 檔出現。要執行 *.rb 檔只不過從以往習慣的 ruby *.rb 改成 jruby *.rb 罷了。

C:\>jruby test.rb


每次看到很多專案使用 RoR (Ruby on Rails) 就很想玩玩,不過我就是看不懂怎麼玩,還是先來學 Ruby 吧。剛好在學校圖書館借到「Ruby Programming - 向 Ruby 之父學程式設計」一書,而且可以到暑假後開學再還,加上有 JRuby 這麼有趣的東西,真該好好學習啊orz

2006/12/20

Ruby 變數, 決策 及迴圈

今天也學了 Ruby。

Ruby 的變數

在程式語言中很重要的變數,在 Ruby 中是怎樣呈現呢?
答案是物件。他將每個變數都視成物件,這跟 Java 有點像 (另一個我在學的語言)
但是 Java 好歹還有 Primitive Data Type (原始資料型態),例如 int i = 9;
這個 i 並不是物件,他脫離了物件導向的精神,而有一些人就在這地方批評 Java 不夠 OO。

Ruby 呢?連數字都是個物件!
比方說 -111.abs 是一個 -111 的 Numeric 物件,呼叫其 abs (取絕對值) 方法,結果是 111。
而 47.6.round 是四捨五入方法 (類似還有 .ceil 取>=的整數, .floor 取<=的整數)
而字串當然不必說,跟 Java 一樣同屬物件。 (ex: 'Hello World'.split)
Ruby 的變數型別比較特別。不需要事先定義變數型別 (ex: Java 的 int i;)
只需要 i = 2 就可以直接使用。而變數依類型也有分:

Constant 常數 : 變數的第一個字元大寫就是了 (ex: PI)
Local Variable 一般變數 : 變數第一個字元小寫就是了 (ex: name)
Global Variable 全域變數 : 變數前加上 $ 錢字符號 (ex: $path)
Instance Variable 實體變數 : 變數前加上 @ 小老鼠 (每個物件生成之後自有的變數)
Class Variable 類別變數 : 變數前加上 @@ 兩隻小老鼠 (物件所屬的類別共有的變數)

其他還有一些事先定義過的符號,因為很難懂所以暫時不提。

Ruby 的決策

說穿了就是其他程式語言的 if - else 而已,Ruby 當然有:

name = 'Tom'
if name == 'Tom'
  p 'Hello Tom, long time no see!'
elsif name == 'Kevin'
  p 'Oh, Kevin. You lent me some money before!'
else
  p "Hey! Your name is #{name}. Isn't it?"
end


需要注意有幾點:

elsif : 不像 Java 的 else if 或是 VB 的 ElseIf,這跟 Perl 的 elsif 一樣
區塊 : 不必跟 C/Java 一樣加大括號,直接打即可,也不必在敘述末加分號
${XXX} : 適用於雙引號時。將變數 XXX 插入字串,跟 PHP 的 "$XXX" 有異曲同工之妙
end : 記得完整的決策是以 end 收尾

除了一般看到的 if,也有變種: (將 if 放在敘述後面)

p 'Long time no see!' if name == 'Tom'


以上一行敘述也可以這樣寫:

if name == 'Tom' then p 'Hello' end


是不是不太一樣呢? Ruby 跟 Perl 有一樣的優點,同一件事可以有多種不同的寫法。
對了,差點忘記方便的三元運算子 ? : , Ruby 也有。

p (name=='Tom' ? 'Long time no see!' : 'Nice to meet you.')


至於方便的 switch,在 Ruby 中叫做 case (就是 switch 裡面的 case 嘛)

case name
  when 'Tom'
    p 'Great'
  when 'Ken'
    p 'Friendly'
  else
    p 'so so'
end


case 後面加的是判斷變數,不像 Java 只支援整數, Ruby 也可以接受文字等。
而且 switch...case 的 case 在 Ruby 用的是 when,而每個 when 判斷之後不必加 :,
而且區塊也不必加什麼 break; 。

Ruby 的迴圈

先從 for 迴圈來吧:

for i in 1..10
  print '*'*i, "\n"
end


以上的意思是讓 i 從 1 跑到 10,而 '*' * i 的意思是讓星號重複 i 遍,
最後再輸出換行字元 (print 可接受多個字串一同輸出),執行結果會印出一個三角形。

當然有其他做法:

10.times{ |i|
  print '*'*(i+1), "\n"
}

以上利用 10 這個 Integer 物件 (隸屬於 Numeric 類別)的 times 方法來跑迴圈,
共跑 10 次,而利用 |i| 方式指派一個 i 變數計數器。會從 0 變到 9。
如此就可以拿來利用。

方法永遠不會只有一種,這在 Ruby 實在是很明顯:

1.step(10){ |i|
  print '*'*i, "\n"
}


以上使用 1 這個隸屬於 Numeric 類別的方法 step 步進跑迴圈。
其中 1 是初始值, .step 內的 10 是結束值,讓 i 這個計數器從 1 跑到 10。
這跟第一個迴圈是相同的。

礙於篇幅只能介紹這些,其實還有 while 迴圈可以用,相關用法可以自行尋找啦。

延伸閱讀:
  • http://www.ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html
    雖然是 1.4 版的過時文件,但其內容相當完整,適合初學者
  • http://www.ruby-doc.org/core/
    類似 Java API 的玩意兒,很完整
  • http://sitekreator.com/satishtalim/index.html
    隨著教學章節開始一步步進入 Ruby 的世界

2006/12/19

用 Ruby 開發 Web 應用程式

哈哈...每天都寫一點學習心得,希望能用三(或更多)個月的時間學好這個語言。
其實標題打的太聳動了點,我還沒那麼厲害馬上學會開發大程式,
不過為了以後能夠玩的更有趣,先來試試如何讓 *.rb 給伺服器執行。

首先要裝 Ruby , *nix 似乎都已經是內建了,實在方便,Windows 就多裝一下應該沒有差。
再來挑個 Web 伺服器,我個人使用 Abyss Web Server X1,他小巧且支援 FastCGI 喔!
首先當然是加入腳本設定,將 *.rb 分給 C:\ruby\bin\ruby.exe 執行,這就是一般 CGI。
注意到 CGI 的輸出要正確,且開頭第一行也要注意 (跟 Perl 一樣啦)

#!/usr/bin/env ruby
puts "Content-Type: text/plain\n\n"


類似這樣的東西,這樣就可以指定輸出純文字格式,後續再看你要輸出什麼 HTML。

而聽說 Ruby 也有 FastCGI,找了一下發現了 ruby-cgi 這個包裹器,
前提要先安裝 fcgi 和 mmap 套件,怎麼試怎麼不成功,後來湊巧把 fcgi套件以純 Ruby 模式安裝上去了,
修改一下 fcgi.rb 前幾行 trap 的錯誤後,好像可以正常執行。 (require "fcgi" 成功)
不過這個 ruby-cgi 包裹器就不知道如何在 Windows 下掛上去,最後先暫時放棄。

發現了 Ruby 自身提供了一個 Web Server 叫做 WEBrick,執行之後即會建立一個 Web Server,
只要設定好 Server 要跑什麼,據說效能比直接 CGI 要快很多。
缺點是得使用獨立的 Web Server 實體和 Port,有點麻煩。我希望能跟 PHP 一樣直接用來執行。
以下就是範例,儲存成 hello.rb 後以 ruby hello.rb 執行即會產生 Web Server 實體。
使用 http://localhost:2000/hello 瀏覽。

#!/usr/local/ruby
require 'webrick'
include WEBrick
s = HTTPServer.new( :Port => 2000 )
class HelloServlet < HTTPServlet::AbstractServlet
def do_GET(req, res)
res.body = "hello, world."
res['Content-Type'] = "text/plain"
end
end
s.mount("/hello", HelloServlet)
trap("INT"){ s.shutdown }
s.start


最後既然 fcgi 好像裝好了,那也來試看看好了,不過感覺上跟 PHP 的 php-cgi 就不太一樣。
網路上的例子:

#!/usr/bin/ruby
require 'cgi'
require 'fcgi'
FCGI.each_cgi{|cgi| cgi.out{'hello, world.'}}


聽說這種模式下速度應該會有飛躍性的提升,可惜我試用 Apache 內建的 ab 來測試運作效率,
提升的並不明顯,可能還是沒設好包裹器的關係吧。

最後,來介紹大家線上學 Ruby,利用 AJAX 寫出來的 irb (Interactive Ruby)
Try Ruby!:http://tryruby.hobix.com/
也有線上教學,輸入 help 就可以一步步操作,感覺還不錯。

距離 RoR 還遠著咧...

2006/12/18

Hello, Ruby!

從今天開始學習 Ruby 吧。

Ruby 是一個腳本語言,所以基本上跟 Perl 很像,不過似乎又不太一樣。
反正學東西的第一步就是要有工具,所以去找了 Ruby 的 Win32 Binary。
有個 One-Click Ruby Installer 可以用,很方便:http://rubyforge.org/projects/rubyinstaller/

安裝完之後因為權限關係,只好手動將系統變數的PATH增加 C:\ruby\bin,
這是 Ruby 的直譯器等程式所在位置。

Ruby 的檔案其副檔名為 *.rb ,而我常用的 EmEditor 剛好有他的 Syntax Highlight 功能。
順便提一下, Ruby 是日本人 "Matz" (まつもとゆきひろ, 松本行弘) 開發的,
目前穩定版是 1.8.5。

緊接著馬上試驗 Ruby:

# ruby -v
ruby 1.8.5 (2006-08-25) [i386-mswin32]


嗯,成功了。

接著是正式撰寫 rb 檔案了。

#!/usr/bin/env ruby
p "Hello".size


存成 hello.rb,以 ruby hello.rb 執行看看:

5


似乎很容易啊?

最後一個:

a = [53,57,368,25678,256,1234,78,3,567,4,57]
p a
p a.sort
p a.reverse


結果是

[53, 57, 368, 25678, 256, 1234, 78, 3, 567, 4, 57]
[3, 4, 53, 57, 57, 78, 256, 368, 567, 1234, 25678]
[57, 4, 567, 3, 78, 1234, 256, 25678, 368, 57, 53]


真棒,有自動排序可用,簡單又方便。原來物件導向就是這樣啊?

結束之前,除了有 ruby 可以用,還有一個 irb 類似即時運算視窗也可以玩玩。

最後感謝這些網站的啟發:
  • http://en.wikipedia.org/wiki/Ruby_programming_language
  • http://polarpolar.infor.org/doc/rubydoc/index.htm


期待有一天能玩到 Ruby on Rails 啦!