跳到主要內容

Ruby

Ruby,一種為簡單快捷物件導向編程而創的腳本語言,在20世紀90年代日本人松本行弘開發,遵守GPL協議和Ruby License[1]。它的靈感與特性來自於PerlSmalltalkEiffelAda以及Lisp語言。由Ruby語言本身還發展出了JRubyJava平台)、IronRuby.NET平台)等其他平台的Ruby語言替代品。

歷史

Ruby的作者松本行弘
Ruby的作者--松本行弘於1993年2月24日開始編寫Ruby,直至1995年12月才正式公開發佈於fj(新聞群組)。之所以稱為Ruby是取法自Perl,因為Perl的發音與6月的誕生石pearl(珍珠)相同,Ruby選擇以7月的誕生石ruby(紅寶石)命名。
Ruby相較之下比其他類似的程式語言(如PerlPython)年輕,又因為Ruby是日本人發明的,所以早期的非日文資料和程式都比較貧乏,在網上仍然可以找到早期對Ruby的資料太少之類的批評。約於2000年,Ruby開始進入美國,英文的資料開始發展。
2004年RoR框架誕生,Ruby更加廣為人知,Ruby並於2006年為TIOBE獲選為年度程式語言。

[編輯] Ruby的理念

減少編程時候的不必要的瑣碎時間,令編寫程序的人高興,是設計Ruby語言的Matz的一個首要的考慮;其次是良好的界面設計。他強調系統設計必須強調人性化,而不是一味從機器的角度設想[2]
人們特別是電腦工程師們,常常從機器著想。他們認為:「這樣做,機器就能運行的更快;這樣做,機器運行效率更高;這樣做,機器就會怎樣怎樣怎樣。」實際上,我們需要從人的角度考慮問題,人們怎樣編寫程序或者怎樣使用機器上應用程序。我們是主人,他們是僕人。
遵循上述的理念,Ruby語言通常非常直觀,按照編程人認為它應該的方式運行。
Ruby的作者認為Ruby > (Smalltalk + Perl) / 2[來源請求],表示Ruby是一個語法像Smalltalk一樣完全物件導向、腳本執行、又有Perl強大的文字處理功能的程式語言。

[編輯] Ruby的Hello World程序

下面是一個在標準輸出設備上輸出Hello World的簡單程序:
#!/usr/bin/env ruby
puts "Hello, world!"
或者是在irb互動式命令列的模式下:
>>puts "Hello, world!"
Hello, world!
=> nil

[編輯] Ruby的特點

[編輯] 變數與函數的命名規則

乍看之下與Perl的命名規則有些類似,不過Perl的命名用來區分純量、陣列與映射;而Ruby的命名規則用來表示變數與類別的關係。Ruby的變數有以下幾種:
  • 一般小寫字母、底線開頭:變數(Variable)。
  • $開頭:全域變數(Global variable)。
  • @開頭:實例變數(Instance variable)。
  • @@開頭:類別變數(Class variable)類別變數被共享在整個繼承鏈中
  • 大寫字母開頭:常數(Constant)。
有些函數則會加一個後綴,用來表示函數的用法,跟變數命名規則不同,函數的命名規則只是習慣,不具強制性,即使你不照規則命名也不影響程式運作
  • =結尾:賦值方法,相當於其他程式語言的set開頭的方法,算是一種語法蜜糖。
  • !結尾:破壞性方法,呼叫這個方法會修改本來的物件,這種方法通常有個非破壞性的版本,呼叫非破壞性的版本會回傳一個物件的副本。
  • ?結尾:表示這個函數的回傳值是個布爾值。

[編輯] 多種字串表示法

Ruby提供了多種字串的表示方法,方便撰寫有大量文字資料的程式。
a = "\n這是一個雙引號的字串\n"
 
a = %Q{\n這是一個雙引號的字串\n}
 
a = <
 
a = %/\t這是一個雙引號的字串\n/
注意上面的字串是會對斜線\進行轉義,假如不希望對\進行轉義,Ruby還提供了其他的字串形式。
a = '這是一個單引號的字串'
a = %q{這是一個單引號的字串}

[編輯] 動態修改物件、類別

Ruby是動態語言,你可以在程序中修改先前定義過的類別。 也可以在某個類別的實例中定義該實例特有的方法,這叫做原型方法(prototype)。
class MyClass
  def the_method
    "general method"
  end
end
 
mc = MyClass.new
def mc.the_method
  "special for this instance."
end
 
mc.the_method

[編輯] 強大的反射機制與元編程

Ruby的反射功能相當驚人,甚至可以自行追蹤程式運作,或是取出private變數、攔截方法的呼叫。 常常與『可以動態的修改物件』這項特色結合,做為『元編程』的功能:程式在運行時, 可以由程式設計師提供的資訊,自行生成、修改類別或物件,這項功能大大的提高了撰寫程式碼的效率。 在RoR之中,就大量使用了這種特性。
以下為用RoR使用元編程的範例:
class Project < ActiveRecord::Base
  belongs_to :portfolio
  has_one    :project_manager
  has_many   :milestones
end
在這個例子中,Project類別繼承Base類別,Base類別內建的belongs_tohas_onehas_many方法,便會根據參數來修改Project類別的內容,並自行建立其他相關的方法。程式設計師可以更專心處理程式的運作,而不必為每個類別重複得撰寫程式碼。

[編輯] 其他特色

  • 完全物件導向:任何東西都是物件,沒有基礎型別
  • 變數沒有類型(動態型別)
  • 任何東西都有值:不管是四則運算、邏輯表達式還是一個語句,都有回傳值。
  • 運算符重載
  • 垃圾回收
  • 弱類型[3]
  • 不必事先宣告變數
  • Windows上,載入DLL

[編輯] 比較與批評

[編輯] 讓人驚訝之處

  • 在Ruby中,只有falsenil表示false,其它的所有值都表示true(包括00.0""[][4]。這點和C語言的『用0代表false』不同,常使用C的人可能會因此驚訝。
  • Ruby的字串是可改變的,這與Java固定不變的字串不同,Java的字串比較像Ruby的Symbol
  • Ruby的繼承功能相當脆弱,儘管Ruby是一個物件導向語言,Ruby內的許多規則,卻使得子類別有可能不小心就覆寫了父類別的功能,在 《The Ruby Programming Language》一書中,建議除非程式設計師對一個類別相當瞭解,否則儘可能不要使用繼承。

[編輯] 和Perl 6比較

  • CPAN上排名第一名,同時也是Perl 6的開發者的唐鳳(Autrijus / Audrey)說:「Ruby就是『沒有到處打廣告的Perl 6』」。[5]
  • 松本行弘在接受歐萊禮(O'Reilly)訪問時,提到「Ruby借用了很多Perl的東西……,Python遠比Perl要少……」、「我認為Ruby這個名字作為Perl之後的一門語言的名字真是再恰當不過了。」[6]
  • Perl之父拉里·沃爾(Larry Wall)說:「很多方面上我還是很喜歡Ruby的,這是因為那些部分是從Perl借過去的。:-)」、「我還喜歡Ruby的C<*>一元星號操作符,所以我把它加到Perl 6里面。」[7]

[編輯] 程式範例

下面的代碼可以在Ruby shell中運行,比如irb互動式命令列,或者保存為文件並運行命令ruby
  • 一些基本的Ruby代碼:
# Everything, including a literal, is an object, so this works:
-199.abs                                                # 199
"ruby is cool".length                                   # 12
"Rick Astley".index("c")                                # 2
"Nice Day Isn't It?".downcase.split(//).sort.uniq.join  # " '?acdeinsty"
  • 一些轉換:
puts "What's your favorite number?"
number = gets.chomp
outputnumber = number.to_i + 1
puts outputnumber.to_s + ' is a bigger and better favorite number.'

[編輯] 集合

a = [1,'hi', 3.14, 1, 2, [4, 5]]
 
p a[2]           # 3.14
p a.[]2# 3.14
p a.reverse      # [[4, 5], 2, 1, 3.14, 'hi', 1]
p a.flatten.uniq # [1, 'hi', 3.14, 2, 4, 5]
  • 構造和使用關聯數組:
hash = { :water => 'wet', :fire => 'hot' }
puts hash[:fire] # Prints:  hot
 
hash.each_pair do |key, value| # Or:  hash.each do |key, value|
puts "#{key} is #{value}"
end
 
# Prints:  water is wet
#          fire is hot
 
hash.delete :water # Deletes :water => 'wet'
hash.delete_if {|k,value| value=='hot'} # Deletes :fire => 'hot'

[編輯] 區塊和迭代器

  • 有兩個語法用於創建區塊:
{ puts "Hello, World!" } # Note the { braces }
#or
do puts "Hello, World!" end
  • 傳參數的區塊使用閉包Closure
# In an object instance variable (denoted with '@'), remember a block.
def remember(&a_block)
  @block = a_block
end
 
# Invoke the above method, giving it a block which takes a name.
remember {|name| puts "Hello, #{name}!"}
 
# When the time is right (for the object) -- call the closure!
@block.call("Jon")
# => "Hello, Jon!"
  • 從方法中返回閉包:
def create_set_and_get(initial_value=0) # Note the default value of 0
  closure_value = initial_value
  return Proc.new {|x| closure_value = x}, Proc.new { closure_value }
end
 
setter, getter = create_set_and_get  # ie. returns two values
setter.call(21)
getter.call # => 21
  • 迭代調用調用時提供的區塊:
def use_hello
  yield "hello"
end
 
# Invoke the above method, passing it a block.
use_hello {|string| puts string} # => 'hello'
  • 使用區塊迭代數組:
array = [1, 'hi', 3.14]
array.each { |item| puts item }
# => 1
# => 'hi'
# => 3.14
 
array.each_index { |index| puts "#{index}: #{array[index]}" }
# => 0: 1
# => 1: 'hi'
# => 2: 3.14
 
(3..6).each { |num| puts num }
# => 3
# => 4
# => 5
# => 6
像inject()方法可以接收一個參數和一個區塊。迭代的注入列表的每一個成員,執行函數時保存總和。這同函數程式語言中的foldl函數相類似,比如:
[1,3,5].inject(10) {|sum, element| sum + element} # => 19
首先區塊接收到了10(inject的參數)當作變數sum,並且1(數組的第一個元素)當作變數element;這會返回11。11又被當作下一步的sum變數,它加上3得到了14。14又被加上了5,最終返回結果19。
  • 區塊運行在內置的方法中:
File.open('file.txt', 'w') do |file| # 'w' denotes "write mode".
  file.puts 'Wrote some text.'
end                                  # File is automatically closed here
 
File.readlines('file.txt').each do |line|
  puts line
end
# => Wrote some text.
  • 使用枚舉器和塊求1到10的平方:
(1..10).collect {|x| x*x} # => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

[編輯] 類別

下面的代碼定義一個命名為Person的類別。含有一個「initialize」方法,用於構選創建一個新對象,它還有兩個方法,一個重載了<=>比較運算符(這樣Array#sort可以使用age排序)另一個重載了to_s方法(這樣Kernel#puts可以格式化輸出),attr_reader是Ruby中元數據編程的例子:attr_accessor為實例變數定義了getter和setter方法,attr_reader只是一個getter方法。另外,方法中最後的聲明是它的返回值,也允許顯式的使用「return」語句。
class Person
  attr_reader :name, :age
  def initialize(name, age)
    @name, @age = name, age
  end
  def <=>(person) # Comparison operator for sorting
    @age <=> person.age
  end
  def to_s
    "#@name (#@age)"
  end
end
 
group = [
  Person.new("Bob", 33),
  Person.new("Chris", 16),
  Person.new("Ash", 23)
]
 
puts group.sort.reverse
  • 下面按age倒序輸出了三個名字:
Bob (33)
Ash (23)
Chris (16)

[編輯] 各種版本

JRuby,類似PythonJython,一個可於Java上執行Ruby的語言,支援Java的介面和類別。最新發佈版為1.6.2 (2011-05-24) ,與Ruby 1.8.7和1.9.2兼容。它的官方網站為jruby.org

留言

這個網誌中的熱門文章

Effortless English - MP3 Free Download ( 167 )

Effortless English - MP3 Free Download ( 167 ) You can download here free AJ Hoge's podcasts, upload them to your mp3 player and improve your English listening at least 30 minutes everyday. To download mp3 click right button of your mouse and select "Save as". Click here to go to the official Effortless English website! General: Power_English_Update.mp3 Models_Etc.mp3 Audio_Twitter_Tweets.mp3 AJ_Update.mp3 Hitch_1_Commentary.mp3 Hitch_1.mp3 Hitch_1_MS-POV.mp3 Hitch_1_MS.mp3 Hitch_1_Vocab.mp3 English_Mastery_Formula.mp3 New_English_Club.mp3 Learn_English_Naturally.mp3 Back_Home.mp3 The_Best_Investment.mp3 Seminar_In_Bangkok_Jan25.mp3 New_Year_Resolution.mp3 Subconscious_Learning.mp3 Intensely.mp3 Super_Fast.mp3 English_Learning_Psychology.mp3 English_Club_2.mp3 Your_First_Lesson.mp3 Business_English_For_New_Business.mp3 Learn_English_Conversation.mp3 Learn_English_Grammar.mp3 Business_vs_Self-Employment.mp3 Learn_Business_English_Eff...

如何將SRT亂碼轉換成繁體字幕

avi格式的電影常常需要搭配srt格式的檔案來顯示字幕,最常見的字幕有英文、簡體中文及繁體中文的格式,不過偶爾會發現出現的字幕是看不懂的文字。若不是翻譯品質的問題,別急著把字幕砍掉,透過幾個小步驟即可轉換為能夠正確顯示的字幕。 1. 打開Word2007,點選"開啟舊檔",將右下角的下拉選單選擇"所有檔案",即可看到.srt檔案。 2. 點選開啟之後,會出現一個選取文字編碼的對話框,選擇"其它編碼方式"中的" 簡體中文GB2312 "語系,預覽框即會出現正確的簡體文字。 3. 選擇工具列上的"校閱">"簡轉繁"功能,將簡體中文轉換為繁體中文。 4. 按Ctrl+A全選、再按Ctrl+C複製所有內容;關閉Word且不要存檔。此時會出現對話框詢問是否要保留複製的文字,按下"是"後離開Word。 5.將剛才的.srt檔案用記事本開啟,將所有的內容文字刪除,再按Ctrl+V將剛剛複製的內容貼上,覆蓋,存檔並關閉就OK了。 另一個快速將亂碼改為簡體中文的方法: 1. 將srt檔案用IE開啟 2. 開啟出來的畫面顯示出來的也是亂碼,接著按右鍵選擇"編碼",選取"簡體中文(GB2312)"的選項,會出現正確的簡體文字。 3.將網頁上的文字複製下來,再用記事本開啟.srt檔案,將原有的亂碼內容刪掉、並貼上剛剛複製的文字,存檔關閉,若有出現對話框,存檔類型選擇"所有檔案",編碼改為"Unicode",按下儲存就完成囉!