Ruby å Rails å
¥é¨
è´¡ç®è
ï¼
Chris Kutler
2007 å¹´ 12 æ [修订å?·ï¼V6.0-2]
æ¬æç¨å°å¸¦ç»æ¨ä¸æ®µæå
³ NetBeans IDE ä¸ Ruby å Ruby on Rails åºç¨ç¨åº?å¼å?çæé£ä¹æ
ãæ¬æç¨å°éè¿å®æ?åºç¨ç¨åº?å¼å?ä¸çå 个å
¸åé¶æ®µæ?¥å?æ¨å±ç¤ºå¦ä½ä½¿ç¨ IDE ç Ruby æ¯æ?æ?¥è¿è¡åºç¨ç¨åº?å¼å?ã
ç±äºæ¬æç¨ç设计使ç¶ï¼æ¨ä¸?å¿
æä»»ä½ç¹å®ç顺åº?è¿è¡å¦ä¹ ãæ¨å?¯ä»¥å¿«éå°æµ?è§æ¬æç¨ï¼ç¶å?卿¶é´å
?许çæ
åµä¸å顾å?个é¨åã妿æ¨å欢æé¨å°±ç?çæç¨ï¼æ¨å?¯ä»¥å
å°?è¯ä¸ä¸ 10 åéå建 Ruby Weblog ã
ç®å½
æç¨éæ±
å¦ä¹ æ¬æç¨éè¦?以䏿æ¯åèµæº?ï¼
å?è§?å®è£
åé
?ç½® Ruby æ¯æ? 䏿以è·å?æå
³å®è£
åé
?ç½® NetBeans Ruby æ¯æ?以å?ä» NetBeans Ruby on Rails 项ç®ä¸ä½¿ç¨æ°æ?®åºæ?å¡å¨å·¥ä½çä¿¡æ?¯ã
æè°é¡¹ç®ï¼å®ç¸å½äºä¸ä¸ªåºç¨ç¨åº?çå·¥ä½ç¯å¢ã彿¨å建ä¸ä¸ªæ°ç Ruby é¡¹ç®æ¶ï¼æ¨å?¯ä»¥éæ©ä½¿ç¨å·²ææä»¶å建项ç®ï¼æè
为æ¨ç Ruby 项ç®ä½¿ç¨æ¨¡æ?¿å建ä¸ç»æ°æä»¶å¤¹ã
注æ?ï¼ å½æ¨æå¼ä¸ä¸ªå¨ IDE ä¹å¤æå»ºçå·²æ Ruby æ JRuby é¡¹ç®æ¶ï¼IDE å¯¹è¯¥é¡¹ç®æå?çä¸ NetBeans 软件ç¸å
³çå¯ä¸æ¹å¨ï¼ä»
ä»
æ¯å建ä¸ä¸ªå??为 nbproject çæä»¶å¤¹ï¼ç¨ä»¥åå¨ NetBeans å
æ°æ?®ã
æ¨å?¯ä»¥å¨ IDE ä¸å?æ¶æå¼å¤ä¸ªé¡¹ç®ã彿¨æå¼è¶
è¿ä¸ä¸ªé¡¹ç®æ¶ï¼æ¨å¿
é¡»æå® å
¶ä¸ä¸ä¸ªä¸ºä¸»é¡¹ç®ãä¸»é¡¹ç®æ¯å½æ¨ç¹å»âè¿?è¡ä¸»é¡¹ç®â?æé®æ¶ IDE æè¿?è¡çé£ä¸ªãè¦?åæ?¢ä¸»é¡¹ç®ï¼å¨â项ç®â?çªå?£ä¸å?³é®ç¹å»ä¸ä¸ªé¡¹ç®ï¼ç¶å?éæ©â设置为主项ç®â?ã
彿¨å建ä¸ä¸ªæ°ç Ruby é¡¹ç®æ¶ï¼IDE ä¼é»è®¤å建ä¸ä¸ªå??为 main.rb çæä»¶ï¼å¹¶å°è¯¥æä»¶è®¾ç½®ä¸ºä¸»èæ¬ã彿¨ç¹å»âè¿?è¡ä¸»é¡¹ç®â?æé®ï¼ ï¼æ¶ï¼IDE ä¼ä¿?åæææä»¶æ¹å¨å¹¶è¿?è¡ä¸»èæ¬ãè¦?åæ?¢è³ä¸ä¸ªä¸?å?çå?¯å¨èæ¬ï¼å¨â项ç®â?çªå?£ä¸å?³é®ç¹å»é¡¹ç®èç¹ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©â屿§â?ãéæ©âè¿?è¡â?æ ?ç®ï¼ç¶å?å¨âä¸»èæ¬â?ææ¬æ¡ä¸é®å
¥æä»¶å??ã
注æ?ï¼ main.rb æä»¶æ¯ä¸º Ruby 项ç®å建ã彿¨å建ä¸ä¸ª Ruby on Rails é¡¹ç®æ¶ï¼å¦å¨å建 Ruby on Rails é¡¹ç® ä¸èæç¤ºï¼IDE ä¸?ä¼å建 main.rb æä»¶ã
è¯è¯ç
ä¸é?¢å?³ä¸ºå建 Ruby 项ç®çæ¥éª¤ã
妿æ¨å°æªå¼å§ï¼é£ä¹é¦å
使ç¨ä¸é?¢æåçé彿¥éª¤å?¯å¨ IDEï¼
Windowsã?Solaris å Linux å?å» NetBeans æ¡é?¢å¾æ ã
Mac å?å»å®è£
æä»¶å¤¹ä¸ç NetBeans 徿 ã
å?³é®å?å»â项ç®â?çªå?£ä¸ç空ç½å¤ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âæ°å»ºé¡¹ç®â?ã
å¨âæ°å»ºé¡¹ç®â?å?导ä¸ï¼éä¸âç±»å«â?é?¢æ?¿ä¸ç Rubyï¼éä¸â项ç®â?é?¢æ?¿ä¸çâRuby åºç¨ç¨åº?â?ï¼ç¶å?ç¹å»ä¸ä¸æ¥ã妿æ¤é¡¹ç®æ¯æ¨æå¼æå建ç第ä¸ä¸ª Ruby 项ç®ï¼åå?¯è½ä¼åºç°ä¸ä¸ªå¯¹è¯?æ¡ï¼è¦?æ±æ¨éæ©ä¸ä¸ª Ruby è§£éå¨ãå¨è§£éå¨é项ä¸éä¸ä¸ä¸ªï¼ç¶å?ç¹å»âç¡®å®â?ã
ç»é¡¹ç®å½å??ï¼ä¾å¦ simple_ruby_application ï¼ç¶å?ç¹å»â宿?â?ã
IDE ä¼å¨ç¼è¾å¨ä¸æ¾ç¤º main.rb æä»¶ãçæ?代ç ?æ¯å¦ä½è°ç¨ puts æ?¥æ¾ç¤ºå符串âHello Worldâ?çã
â项ç®â?çªå?£å±ç¤ºäºé¡¹ç®æä»¶çé»è¾è§å¾ãç¹å»âæä»¶â?é项å?¡æ¥çç©ç?å¸å±ï¼ç¶å?åæ?¢å, å¼å
³â项ç®â?çªå?£ãå¯¹äº Ruby 项ç®ï¼è¿ä¸¤ä¸ªè§å¾æ¯å¾ç¸ä¼¼çã
ç¹å»âè¿?è¡ä¸»é¡¹ç®â?æé®ï¼ ï¼è¿?è¡åºç¨ç¨åº?ã
IDE ä¼å¨å
¶åºé¨ççªå?£ä¸æ¾ç¤ºè¾åºï¼å¦ä¸å¾æç¤ºã
å¾ 1ï¼âè¾åºâ?çªå?£
æ?ä½ Ruby é¡¹ç®æä»¶ä¸ä½¿ç¨ææ¬ç¼è¾å¨å¤ç?å®ä»¬æ¯è¾ç±»ä¼¼ãæ¨å?¯ä»¥éè¿å?å»â项ç®â?çªå?£æè
âæä»¶â?çªå?£ä¸çæä»¶èç¹æå¼æä»¶ãæ¨ä¹å?¯ä»¥æä¸âAlt-Shift-Oâ?ç»å?é®ï¼å¨ Mac ä¸è¯·ä½¿ç¨âCtrl-Shift-Oâ?ç»å?é®ï¼æ?¥éè¿æä»¶å??è®¿é®æä»¶ã
IDE çç¼è¾å¨æ??ä¾äºå¾å¤ç¹æ§æ?¥å¸®æ¨å®æ?ç¨åº?设计çä»»å¡ãæ¨å°å¨æ¬èå¦ä¹ ä¸äºåºæ¬çç¼è¾ç¹æ§ã宿´çç¼è¾ç¹æ§å表å?¯ä»¥å?è NetBeans Ruby Editing Wiki 页é?¢ã
è¯è¯ç
ä¸é?¢çæ¥éª¤å°å建ä¸ä¸ªç¨ä»¥æ¾ç¤ºäº§å?å表çç®å?ç Ruby 项ç®ãé¦å
ï¼ä¸ºä¸ä¸ªå?ç¬ç产å?æ?¡ç®å建ä¸ä¸ªç±»ãç¶å?ï¼ä¸ºæ?¡ç®å表å建ä¸ä¸ªç±»ï¼ä»¥å?ä¸ä¸ªæ°æ?®æä»¶æ?¥æ??ä¾äº§å?æ°æ?®ãæå?ï¼ç¼ç¼ main.rb æä»¶æ¾ç¤ºå表ãå¨å¼å?代ç ?çå?æ¶ï¼è¿äºæ¥éª¤ä¹ä¼ä»ç»?ç¼è¾ç¹æ§ã
å建 Item ç±»
å建ä¸ä¸ª Ruby 项ç®ï¼æè
ä½¿ç¨æ¨å¨å?ä¸è䏿å建çé£ä¸ªã
å¨ â项ç®â?çªå?£ä¸ï¼å?³é®ç¹å»âæº?æä»¶â?èç¹ï¼å¨å¼¹åºè?å?ä¸éæ©âæ°å»ºâ?->âRuby ç±»â?ï¼å建ä¸ä¸ªç±»æä»¶ãå¨âç±»â?ææ¬æ¡ä¸é®å
¥ Item ï¼ç¶å?ç¹å»â宿?â?ã
IDE ä¼å建ä¸ä¸ªå??为 item.rb çæä»¶ï¼å¹¶å¨ç¼è¾å¨ä¸å°å
¶æå¼ã
å° item.rb æä»¶ä¸çå
å®¹æ¿æ?¢æ?ä¸é?¢ä¸?æ£ç¡®ç代ç ?ãæ¨å°å¨ä½ä¸çæ¥éª¤ä¸ä¿®æ£è¿äºä»£ç ?ã
代ç ?ç¤ºä¾ 1ï¼Item ç±»
class Item
def initialize(id, type, price)
end
def simple_method(id, type, price)
@id = id
@type = type
@price = price.to_f
end
def to_s
"Item #{@id} is a #{@type}: Price $#{@price}"
end
end
卿º?æä»¶ä¸ç¹å»å?³é®ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âæ ¼å¼?å代ç ?â?ï¼æ ¼å¼?å代ç ?ã
çæ? initialize æ¹æ³çå?æ°ä¸é?¢çç?°è²æ³¢æµªçº¿ï¼å¦ä¸å¾æç¤ºãè¿äºçº¿æ 示åºäºæªä½¿ç¨çå?é?ãæ¨å°å¨å?é?¢ä¸¤ä¸ªæ¥éª¤ä¸ä¿®æ£è¯¥é误ã
å¾ 2ï¼æªä½¿ç¨çå?é?
å°å
æ ç½®äº @type ï¼ä½?äº simple_method ä¸ï¼ï¼ç¶å?æä¸âAlt-Shift-Periodâ?ç»å?é®ï¼Period æ¯å?¥ç¹å?·ï¼å¨ Mac ä¸è¯·ä½¿ç¨âCtrl-Shift-Periodâ?ç»å?é®ï¼æ?¥éä¸è¯¥è¡ãå?䏿¬¡æä¸æé®ç»å?æ?¥éä¸å?ï¼å¦ä¸å¾æç¤ºã
å¾ 3ï¼å¤è¡éæ©
卿º?æä»¶ä¸ç¹å»å?³é®ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âåªåâ?ã
å°å
æ ç½®äºæé 彿°å¤´é¨ï¼initialize æ¹æ³ï¼ï¼ç¶å?æä¸âShift-Enterâ?ç»å?é®ï¼å¨å½å?è¡ä¸æ·»å ä¸ä¸ªæ°è¡ã卿°è¡å¤ç¹å»å?³é®ï¼ç¶å?ä»å¼¹åºå¼?è?å?ä¸éæ©âç²è´´â?ã
simple_method æ¹æ³çç®ç忝æ?¥ä¿?åä¹å?æ¥éª¤ä¸æéç代ç ?ãç°å¨ï¼æ¨å?¯ä»¥å°æ¤æ¹æ³å 餿ãé¦å
ï¼å°å
æ ç½®äº simple_method æ¹æ³ç end è¯å?¥å¤ã
çæ? IDE ä¼é«äº®æ¾ç¤ºå
¶å¯¹åºç def è¯å?¥ã
æä¸âAlt-Shift-Periodâ?ç»å?é®ï¼Period æ¯å?¥ç¹å?·ï¼å¨ Mac ä¸è¯·ä½¿ç¨âCtrl-Shift-Periodâ?ç»å?é®ï¼æ?¥éä¸è¯¥æ¹æ³ï¼ç¶å?æä¸âBackSpaceâ?é®å°å
¶å é¤ã
å°å
æ ç½®äºç©ºè¡å¤ï¼æä¸âCtrl-Eâ?ç»å?é®ï¼å¨ Mac ä¸è¯·ä½¿ç¨âCmd-Eâ?ç»å?é®ï¼å°å
¶å é¤ã
æ¥ä¸æ?¥çå æ¥å°å±ç¤ºå¦ä½ä½¿ç¨ä»£ç ?è¡¥å
¨åè½ãå¨ç±»å?顶鍿å¼ä¸ä¸ªç©ºè¡ï¼å°å
æ ç½®äºè¯¥è¡å¤ï¼é®å
¥ attr_a ï¼ç¶å?æä¸âCtrl-Spaceâ?ç»å?é®ï¼è¥âCtrl-Spaceâ?ç»å?é®å¨æ¨çç³»ç»ä¸æ æï¼è¯·ä½¿ç¨âCtrl-\â?ç»å?é®ï¼ã
IDE 伿¾ç¤ºä¸ä¸ªå表ï¼ååºå?¯è½ç代ç ?è¡¥å
¨ï¼å¦ä¸å¾æç¤ºã
å¾ 4ï¼attr_a ç代ç ?è¡¥å
¨å表
éæ© attr_accessor :attr_names rwï¼ç¶å?æä¸âEnterâ?é®ã
IDE å°è¡¥å
¨ä»£ç ?ï¼å¹¶éæ© attr_names ç¨äºç¼è¾ï¼å¦ä¸å¾æç¤ºã
å¾ 5ï¼è¡¥å
¨ç代ç ?
é®å
¥ id, :type, :price æ?¥å®æ?è¯å?¥ï¼ç¶å?æä¸âEnterâ?é®ã
è¯å?¥åºå¦ä»¥ä¸ä»£ç ?æç¤ºã
attr_accessor :id, :type, :price
éæ© attr_accessor æ¹æ³çæ¯?ä¸ä¸ªå?æ°ï¼çæ? IDE ä¼é«äº®æ¾ç¤ºæ¯?ä¸ªå±æ§ç使ç¨ã
宿?å?çèæ¬åºå¦ä»¥ä¸ä»£ç ?ç¤ºä¾æç¤ºã
代ç ?ç¤ºä¾ 2ï¼æ ¼å¼?åå?ç Item ç±»
class Item
attr_accessor :id, :type, :price
def initialize(id, type, price)
@id = id
@type = type
@price = price.to_f
end
def to_s
"Item #{@id} is a #{@type}: Price $#{@price}"
end
end
å建 ItemsList ç±»
å¨â项ç®â?çªå?£ä¸ï¼å?³é®ç¹å»âæº?æä»¶â?èç¹ï¼å¨å¼¹åºè?å?ä¸éæ©âæ°å»ºâ?->âRuby ç±»â?ï¼å建å?¦ä¸ä¸ªç±»æä»¶ãå¨âç±»â?ææ¬æ¡ä¸é®å
¥ ItemsListï¼ç¶å?ç¹å»â宿?â?ãæ³¨æ?ï¼IDE ä¼å°æä»¶å½å??为 items_list.rb ã
ç¨ä¸åè¯å?¥æ¿æ?¢ items_list.rb æä»¶çå
容ã
代ç ?ç¤ºä¾ 3ï¼ItemsList ç±»
class ItemsList
DATA_FILE="data.txt"
attr_accessor :items
def initialize
@items = ItemsList.load_item_data
end
private
def self.load_item_data
items = []
File.open(DATA_FILE) do |data_file|
data_file.readlines.each do |line|
items << Item.new(*line.split("\s"))
end
end
items
end
end
å¨ç±»å®ä¹å?é?¢æå¼ä¸ä¸ªç©ºè¡ï¼å¹¶é®å
¥ require' ï¼å?å¼å?·ï¼ã
çæ? IDE 伿??ä¾ç»å°¾å¤çå?å¼å?·ï¼å¹¶å°å
æ ç½®äºä¸¤ä¸ªå¼å?·å
é¨ï¼å¦ä¸å¾æç¤ºã
IDE è½èªå¨æ?å
¥æè
å é¤å¹é
?çåé符ï¼å¦å¼å?·ã?è±æ¬å?·ã?å°?æ¬å?·ï¼ä»¥å?代ç ?å?ç end è¯å?¥ççã
å¾ 6ï¼åé符对å¹é
?
å
æ ä½?äºå¼å?·å
é¨ï¼é®å
¥ it ï¼ç¶å?æä¸âCtrl-Spaceâ?ç»å?é®ãä»
æä¸é¡¹å?¯ç¨ç import æ¯ä»¥âitâ?å¼å¤´çï¼å¦ä¸å¾æç¤ºãæä¸âTabâ?鮿¥å?该é项ã
å¾ 7ï¼require è¯å?¥ç代ç ?è¡¥å
¨
åå»ºæ°æ?®æä»¶
å¨â项ç®â?çªå?£ä¸ï¼å?³é®ç¹å»âæº?æä»¶â?èç¹ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âæ°å»ºâ?>âå
¶ä»â?ãå¨âç±»å«â?é?¢æ?¿ä¸éæ©âå
¶ä»â?ï¼å¨âæä»¶ç±»åâ?é?¢æ?¿ä¸éæ©â空æä»¶â?ï¼ç¶å?ç¹å»âä¸ä¸æ¥â?ã
å¨âæä»¶å??â?ææ¬æ¡ä¸é®å
¥ data.txt ã
ç¡®ä¿?âæä»¶å¤¹â?被设置为 lib ï¼ç¹å»â宿?â?ã
注æ?ï¼ æ¨æ£å°è¯¥ææ¬æä»¶æ¾ç½®å¨ lib æä»¶å¤¹ä¸ï¼å 为ï¼å¨é»è®¤æ
åµä¸ï¼å½æ¨ä» IDE ä¸è¿?è¡é¡¹ç®æ¶ï¼é»è®¤çå·¥ä½ç®å½å?³ä¸º lib æä»¶å¤¹ã
å°ä¸åææ¬ç²è´´è³ data.txt æä»¶ä¸ã
代ç ?ç¤ºä¾ 4ï¼äº§çæ°æ?®
BF15678 book 25.32
C29589 cd 18.95
F89028 beverage 2.00
BN98232 book 45.33
BF15890 book 15.98
åå»ºä¸»èæ¬å¹¶è¿?è¡åºç¨ç¨åº?
å¨â项ç®â?çªå?£ä¸ï¼å?å» main.rbï¼å°å
¶æ¾ç¤ºå¨ç¼è¾å¨çªå?£ä¸ã使ç¨ä¸åè¯å?¥æ¿æ?¢å
¶å
容ï¼è¿äºè¯å?¥å°æ¾ç¤ºæ?¡ç®å表ï¼
代ç ?ç¤ºä¾ 5ï¼ç¨äº main.rb çå
容
require 'items_list'
items_list = ItemsList.new
items_list.items.each do |item|
line_item = item.to_s
line_item.gsub!(/book/, 'fiction \0') if item.id =~ /\AB[FN]/
line_item.gsub!(/fiction/, 'non-\0') if item.id =~ /\ABN/
puts line_item
end
puts "\n"
ååå¤?å¶ç代ç ?ä¸å
å?«ä¸¤ä¸ªæ£å表达å¼?对象ï¼/\AB[FN]/ å /\ABN/ ãå°å
æ ç½®äºå
¶ä¸ä¸ä¸ªæ£å表达å¼?对象å
é¨ï¼å¦ä¸æç¤ºï¼å¹¶æä¸âCtrl-Spaceâ?ç»å?é®ã IDE 伿¾ç¤ºä¸ä¸ªåææ£å表达å¼?å符å?å符ç»å?çå表ãçä¸ä¸ä»£ç ?ç¤ºä¾ 5 ä¸çæ°æ?®ï¼å¹¶çæµä¸ä¸åªä¸ªæ?¡ç®ä¼è¢«è¿ä¸¤ä¸ªæ£å表达å¼?åå«å¹é
?ã
å¾ 8ï¼æ£å表达å¼?ç代ç ?è¡¥å
¨
ç¹å»ä¸»å·¥å
·æ ?ä¸çâè¿?è¡ä¸»é¡¹ç®â?æé®æ?¥è¿?è¡é¡¹ç®ã
IDE ä¼ä¿?åæææ¹å¨ï¼å¹¶è¿?è¡ main.rb èæ¬ãåºç¨ç¨åº?çè¾åºå°ä¼åºç°å¨âè¾åºâ?çªå?£ä¸ï¼å¦ä¸å¾æç¤ºã
å¾ 9ï¼simple_ruby_application çè¾åº
为äºç»ä¹ ä¸ä¸ç®å?æå¦å°çå
容ï¼å建 å?¦ä¸ä¸ª Ruby 项ç®ãé
读项ç®ï¼å¹¶å¨ä»»å¡åè¡¨ä¸æ¾ç¤ºæ?¡ç®ã
æ´å¤ä¿¡æ?¯
å¨ IDE ä¸å建 Ruby on Rails 项ç®ä¸å¨ç»ç«¯çªå?£ä¸ä½¿ç¨ rails å½ä»¤å??å类似ãå®é
ä¸ï¼å½æ¨åå»ºé¡¹ç®æ¶ï¼IDE ä¼åå»ºä¸ rails æå建çç¸å?çæä»¶å¤¹åæä»¶ã
å建ä¸ä¸ªé¡¹ç®ï¼å?¯ä»¥éè¿å¨â项ç®â?çªå?£ä¸å?³é®ç¹å»ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âæ°å»ºé¡¹ç®â?æ?¥å®ç°ãå¨âç±»å«â?é?¢æ?¿ä¸éæ©âRubyâ?ï¼å¨â项ç®â?é?¢æ?¿ä¸éæ©âRuby on Rails åºç¨ç¨åº?â?æè
âå
å?«å·²æä»£ç ?ç Ruby on Railsåºç¨ç¨åº?â?ã
æ¨å?¯ä»¥å¨ IDE ä¸å?æ¶æå¼å¤ä¸ªé¡¹ç®ã主项ç®ï¼NetBeans å¨ä½å®é
æ?ä½ç项ç®ï¼èç¹ä¼ä»¥ç²ä½æ¾ç¤ºãè¦?åæ?¢ä¸»é¡¹ç®ï¼å¨â项ç®â?çªå?£ä¸å?³é®ç¹å»ä¸ä¸ªé¡¹ç®ï¼ç¶å?éæ©â设置为主项ç®â?ã
å¦ä¸å¾æç¤ºï¼âæ°å»ºé¡¹ç®â?å?导ç第äºä¸ªé¡µé?¢è®©æ¨å¯¹é¡¹ç®è¿è¡å½å??ï¼å¹¶æå®å
¶ä½?ç½®ãå¨ä¸æåè¡¨ä¸æ??ä¾äºä¸äºæ¯æ?çæ°æ?®åºæ?å¡å¨å??ç§°ãIDE 使ç¨éå®çæ°æ?®åºæ?å¡å¨ä»¥å?âä½¿ç¨ JDBC è®¿é®æ°æ?®åºâ?é项æ?¥å³å®å¦ä½å¯¹ database.yml æä»¶åå
¥å
容ã
å¾ 10ï¼âæ°å»º Ruby on Rails 项ç®â?å?导ç第äºé¡µ
è¯è¯ç
æå¦ä¸æ¥éª¤æ?¥å建ä¸ä¸ª Ruby on Rails 项ç®ã
å?³é®ç¹å»â项ç®â?çªå?£ä¸ç空ç½å¤ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âæ°å»ºé¡¹ç®â?ã
å¨âæ°å»ºé¡¹ç®â?å?导ä¸ï¼éä¸âç±»å«â?çªæ ¼ä¸ç Rubyï¼éä¸â项ç®â?çªæ ¼ä¸çâRuby on Railsåºç¨ç¨åº?â?ï¼ç¶å?ç¹å»âä¸ä¸æ¥â?ã妿æ¤é¡¹ç®æ¯æ¨æå¼æå建ç第ä¸ä¸ª Ruby 项ç®ï¼åå?¯è½ä¼åºç°ä¸ä¸ªå¯¹è¯?æ¡ï¼è¦?æ±æ¨éæ©ä¸ä¸ª Ruby è§£éå¨ãå¨è§£éå¨é项ä¸éä¸ä¸ä¸ªï¼ç¶å?ç¹å»âç¡®å®â?ã
å½å??该项ç®ï¼å¦ simple_rails_application ã
æ¥ä¸æ?¥ï¼éæ©åºç¨ç¨åº?è¦?使ç¨çæ°æ?®åºæ?å¡å¨ãè¥æ£å¨ä½¿ç¨ JRubyï¼åå¿
须鿩 MySQLã?PostgresSQLã?Oracleã?HSQLDB æè
Java DBï¼ä¹ç§°ä¸º Derbyï¼ã
IDE 使ç¨è¿äºä¿¡æ?¯æ?¥å?å§å database.yml æä»¶ã
注æ?ï¼ è¥ä»
卿¬æç¨ä¸ä½¿ç¨æ¤é¡¹ç®ï¼åæ é访é®ä»»ä½æ°æ?®åºï¼æ
å?¯ä»¥æ¥å?é»è®¤çæ°æ?®åºè®¾ç½®ã
è¥æ£å¨ä½¿ç¨ JRubyï¼ä¸è®¿é® MySQL ä¹å¤çæ°æ?®åºæ?å¡å¨ï¼åå¿
é¡»éä¸âä½¿ç¨ JDBC è®¿é®æ°æ?®åºâ?å¤?éæ¡ãè¥æ°æ?®åºæ?å¡å¨æ¯ MySQLï¼åæ¯å?¦ä½¿ç¨ JDBC æ¯å?¯éçã
å½éä¸è¯¥å¤?éæ¡æ¶ï¼IDEä¼å? environment.rb æä»¶ä¸æ·»å è¯å?¥ï¼ä½¿ç¨ ActiveRecord-JDBC gemã
注æ?ï¼ è¦?ä½¿ç¨ JDBC è¿æ¥ï¼å¿
é¡»è·å?æç¨æ°æ?®åºæ?å¡å¨ç JDBC 3.0 客æ·ç«¯é©±å¨ç¨åº?ï¼å¹¶å°è¯¥ JDBC 驱å¨ç¨åº?çä¸ä»½æ·è´?æ¾ç½®å¨ JRuby/lib æä»¶å¤¹ä¸ã
ç¹å»â宿?â?ã
å¨â项ç®â?çªå?£ä¸æ£æ¥æä»¶ç»æçé»è¾è§å¾ã
å?³é®ç¹å»é¡¹ç®èç¹ï¼é¡¹ç®çæ ¹èç¹ï¼ï¼çæ?è?å?é项ã
ç¹å»âæä»¶â?é项å?¡ï¼æ¯è¾ä¸ä¸æ¤ç©ç?æä»¶ç»æåâ项ç®â?çªå?£ä¸æ¾ç¤ºçé»è¾è§å¾ã
ä¸å¾å°çªå?£åååºæ?¥ï¼ä¾¿äºä¸¤ä¸ªè§å¾ç对æ¯ã
å¾ 11ï¼â项ç®â?çªå?£ä¸âæä»¶â?çªå?£çæ¯è¾
å¨âæä»¶â?çªå?£ä¸å?³é®ç¹å»é¡¹ç®èç¹ï¼ä¸â项ç®â?çªå?£ä¸çå¼¹åºè?å?ç¸æ¯è¾ï¼çæ?è?å?é项çä¸?å?ã ä¾å¦ï¼â项ç®â?çªå?£ä¸é¡¹ç®èç¹çå¼¹åºè?å?æ??ä¾äºâçæ?â?å¨ä½ã?âè¿?è¡ Rake ä»»å¡â?å¨ä½ã?âRails æ§å¶å?°â?å¨ä½ï¼ä»¥å?许å¤å
¶ä» Rails ç¸å
³çå¨ä½ã
é¤äº Ruby 项ç®ï¼NetBeans Ruby æ¯æ?ä¹è½æ?ä½ Ruby on Rails 项ç®ãRails æ¯ä¸ç§?å
?许快éåå»ºä»¥æ°æ?®åºä¸ºå?端ã?åºäºæ¨¡å-è§å¾-æ§å¶å¨ï¼MVCï¼ç»æç Web åºç¨ç¨åº?çæ¡æ¶ã
å Ruby 项ç®ä¸æ ·ï¼å¨ç¼è¾å¨ä¸æå¼æä»¶å?¯ä»¥éè¿å¨â项ç®â?çªå?£æè
âæä»¶â?çªå?£ä¸å?廿件èç¹ï¼æè
éè¿æä¸âAlt-Shift-Oâ?ç»å?é®ï¼å¨ Mac ä¸è¯·ä½¿ç¨âCtrl-Shift-Oâ?ç»å?é®ï¼ä½¿ç¨æä»¶å??è®¿é®æä»¶ã
â项ç®â?çªå?£ä¸èç¹çå¼¹åºè?å?æ??ä¾äº Rails èæ¬å Rake ä»»å¡ç便å©è®¿é®ï¼å¦ç¨äºçæ?代ç ?ç generate èæ¬ã?ç¨äºå°æ°æ?®åºè¡¨è¿?ç§»è³ç¹å®çæ¬ç db:migrate ä»»å¡ã
IDE è½å¤ç?è§£æä»¶ç±»åä¹é´çå
³ç³»ï¼èä¸è½æ¹ä¾¿ç导èªè³ç¸å
³æä»¶ãä¾å¦ï¼å¦ææ¨æ£å¨ç¼è¾ä¸ä¸ªè§å¾æä»¶ï¼æ¨å?¯ä»¥ä½¿ç¨å¼¹åºè?å?导èªè³å
¶ç¸å
³çå¨ä½æä»¶æè
æµè¯ã
䏿æ NetBeans 项ç®ä¸æ ·ï¼å?¯ä»¥éè¿ç¹å»âè¿?è¡ä¸»é¡¹ç®â?æé®æ?¥è¿?è¡åºç¨ç¨åº?ãIDE ä¼ä¿?åæææä»¶æ¹å¨ï¼å¦å¿
è¦?çè¯?å?¯å¨ web æ?å¡å¨ï¼ç¶å?卿µ?è§å¨ä¸æ¾ç¤ºæ¬¢è¿é¡µé?¢ãæ¨ä¹å?¯ä»¥ä½¿ç¨ç¼è¾å¨ä¸çâè¿?è¡æä»¶â?è?å?å¨ä½ä»¥ç¸å
³ç URL 卿µ?è§å¨ä¸æå¼æ¨æ£å¨ç¼è¾çæ 论æ§å¶å¨ã?å¨ä½ã?è§å¾ææ¯å¸®å©æä»¶ã
è¯è¯ç
宿?ä¸åæ¥éª¤æ?¥å建å¨ä½¿ç¨ Ruby æä»¶ ä¸è䏿å±ç¤ºçæ ·ä¾é¡¹ç®ç Rails çæ¬ã卿¤å?ä½ä¸ï¼æé 彿°å°ä½¿ç¨æ£åèä¸?æ¯ä½?ç½®å?æ°ï¼è·å?æ°æ?®æ¯ä» YAML æä»¶ä¸ï¼èä¸ Item ç±»ä¸ ItemsList åè½è¢«å 餿äºã
注æ?ï¼ å
¸åçï¼å¨ Rails 项ç®ä¸ï¼æ¨¡åç±»æ¯åºäºæ°æ?®åºè¡¨çãç¶èï¼ä¸ºäºè®©æ¤æ ·ä¾å¿«éä¸ç®å?ï¼åºç¨ç¨åº?å°ä»ä¸ä¸ª YAML æä»¶ä¸è·å?æ°æ?®ã
å建模åç±»
å建ä¸ä¸ª Ruby on Rails 项ç®ï¼æè
ä½¿ç¨æ¨å¨å?ä¸è䏿å建çé£ä¸ªã
å¨â项ç®â?çªå?£ä¸ï¼å?³é®ç¹å»â模åâ?èç¹ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âçæ?â?ã
âRails çæ?å¨â?对è¯?æ¡å°è¢«æå¼ï¼å¨âçæ?â?䏿å表ä¸éæ©â模åâ?ï¼å¦ä¸å¾æç¤ºã
å¾ 12ï¼ä»â模åâ?èç¹è°ç¨çâRails çæ?å¨â?
å¨âå?æ°â?ææ¬æ¡ä¸é®å
¥ Item ï¼ç¶å?ç¹å»â宿?â?ã
IDE ä¼å建ä¸ä¸ªå??为 item.rb çæä»¶ï¼å¹¶å¨ç¼è¾å¨ä¸å°å
¶æå¼ã
è¡¨ç¤ºæ¹æä»¶çèç¹ä¼åºç°å¨â项ç®â?çªå?£ä¸çâæ¨¡åâ?èç¹ä¸ãIDE ä¼å?æ¶å¨âå?å
æµè¯â?ä¸å建ä¸ä¸ªæµè¯å¥ä»¶ã?å¨âæµè¯å¥ä»¶ï¼Fixtureï¼â?ä¸å建ä¸ä¸ªæµè¯å¥ä»¶ã?以å?å¨âæ°æ?®åºè¿?ç§»â?->âè¿?ç§»â?ä¸å建ä¸ä¸ªè¿?ç§»ã
ç¨ä¸å代ç ?æ¿æ?¢ item.rb æä»¶çå
容ã
代ç ?ç¤ºä¾ 6ï¼Item ç±»
# Takes:
# :id => unique item id
# :type => type of item
# :price => price of the item
class Item
DATA_FILE="data.yml"
attr_accessor :id, :type, :price
def initialize(attributes)
@id = attributes['id']
@type = attributes['type']
@price = attributes['price'].to_f
end
def to_s
"Item #{@id} is a #{@type}: Price $#{@price}"
end
def self.load_item_data
YAML.load_file(DATA_FILE).collect do |item_hash|
Item.new(item_hash)
end
end
end
åå»ºæ°æ?®æä»¶
Item ç±»è¦?æ± data.yml
æä»¶ä½ä¸ºå
¶æ°æ?®ãè¦?å建该æä»¶ï¼å¨â项ç®â?çªå?£ä¸ï¼å?³é®ç¹å»é¡¹ç®èç¹ï¼å¨å¼¹åºè?å?ä¸éæ©âæ°å»ºâ?->âå
¶ä»â?ã
å¨âæ°å»ºæä»¶â?对è¯?æ¡ä¸ï¼å¨âç±»å«â?é?¢æ?¿ä¸éä¸âRubyâ?ï¼å¨âæä»¶ç±»åâ?é?¢æ?¿ä¸éä¸âYAML æä»¶â?ï¼ç¹å»âä¸ä¸æ¥â?ã
å¨âæä»¶å??â?ææ¬æ¡ä¸é®å
¥ data ï¼ç¹å»â宿?â?ã
IDE å°å¨é¡¹ç®çæ ¹æä»¶å¤¹ä¸å建ä¸ä¸ªå??为 data.yml çæä»¶ï¼å¹¶å¨ç¼è¾å¨ä¸å°å
¶æå¼ãç±äºè¯¥æä»¶ä½?äºæ ¹æä»¶å¤¹ä¸ï¼æ
æ æ³å¨â项ç®â?çªå?£çé»è¾è§å¾ä¸çå°å®ãä¸?è¿ï¼å®è¿æ¯ä¼åºç°å¨âæä»¶â?çªå?£ä¸ã
ç¨ä¸åææ¬æ¿æ?¢ data.yml æä»¶çå
容ã
代ç ?ç¤ºä¾ 7ï¼data.yml
-
id: BF15678
type: book
price: 25.32
-
id: C29589
type: cd
price: 18.95
-
id: F89028
type: beverage
price: 2.00
-
id: BN98232
type: book
price: 45.33
-
id: BF15890
type: book
price: 15.98
å建æ§å¶å¨åè§å¾
模åå·²ç»?åå¤å¥½äºãç°å¨æ?¥æ·»å æ§å¶å¨åè§å¾ãå¨â项ç®â?çªå?£ä¸ï¼å?³é®ç¹å»âæ§å¶å¨â?èç¹ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âçæ?â?ã
âRails çæ?å¨â?对è¯?æ¡å°è¢«æå¼ï¼å¨âçæ?â?䏿å表ä¸éæ©âæ§å¶å¨â?ï¼å¦ä¸å¾æç¤ºã
å¾ 13ï¼ä»âæ§å¶å¨â?èç¹è°ç¨çâRails çæ?å¨â?
å¨âå??ç§°â?ææ¬æ¡ä¸é®å
¥ Item ï¼å¨âè§å¾â?ææ¬æ¡ä¸é®å
¥ index ï¼ç¹å»âç¡®å®â?ã
IDE å°å建ItemController ç±»ï¼å¹¶å¨âè§å¾â?->âitemâ?ä¸å建 index.rhtml è§å¾ãæ¤å¤ï¼IDE è¿ä¼å建âåè½æµè¯â?->âitem_controller_test_rbâ?åâ帮å©â?->âitem_helper.rbâ?ã
ç¨ä¸å代ç ?æ¿æ?¢ item_controller.rb æä»¶çå
容ã
代ç ?ç¤ºä¾ 8ï¼ItemController ç±»
class ItemController < ApplicationController
def index
@items = Item.load_item_data
end
end
æ§å¶å¨å¨è°ç¨ index è§å¾å?æè°ç¨ç index å¨ä½ï¼ä½¿ç¨æ?¡ç®å表æ?¥å¡«å
@items å
¨å±æ°ç»ã
è¦?å¿«éè®¿é® index.rhtml æä»¶ï¼å¨ index å®ä¹ä¸å?³é®ç¹å»ï¼å¨å¼¹åºè?å?ä¸éæ©â导èªâ?->âè½¬è³ Rails å¨ä½â?æâè½¬è³ Rails è§å¾â?ï¼å¦ä¸å¾æç¤ºã
å¾ 14ï¼å¯¼èªè³è§å¾
使ç¨å¦ä¸æ è®°æ¿æ?¢ index.rhtml æä»¶çå
容ã
代ç ?ç¤ºä¾ 9ï¼index.rhtml
<h1>List of Items</h1>
<table border="1">
<tr><th>Id</th><th>Type</th><th>Price</th></tr>
<% for item in @items %>
<tr>
<td><%= item.id %>
</td>
<td><%= item.type %></td>
<td class="align-right"><%= '%.02f' % item.price %></td>
</tr>
<% end %>
</table>
åµå¨ HTML ä¸ Ruby 代ç ?ä¼é??åç±æ§å¶å¨ä¸ç index å¨ä½æå®ä¹ç @items å
¨å±æ°ç»ã
è¿?è¡åºç¨ç¨åº?
ç¹å»ä¸»å·¥å
·æ ?ä¸çâå
¨é¨ä¿?åâ?æé®æ?¥ä¿?åå
¨é¨æ¹å¨ã
卿件é项å?¡å¤´é¨æä»¶å??å¤çæå?·ï¼*ï¼ï¼è¡¨ç¤ºæä»¶ææ¹å¨ï¼ç°å¨ä¼æ¶å¤±äºã
å¨ç¼è¾å¨ä¸å?å»é¼ æ å?³é®ï¼ç¶å?éæ©âè¿?è¡æä»¶â?ã
IDE æ item æ§å¶å¨å index å¨ä½ç URL å?é?è³æ?å¡å¨ï¼æ?å¡å¨å?å°ä¸å页é?¢å?é?è³æµ?è§å¨ã
å¾ 15ï¼æµ?è§å¨ä¸æ¾ç¤ºç index è§å¾
å?¯ä»¥è¯ç?ç¹å»âè¿?è¡ä¸»é¡¹ç®â?æ?¥è¿?è¡æ´ä¸ªåºç¨ç¨åº?ã
ä¼å?ç°æ åç Ruby on Rails 欢è¿é¡µé?¢å°è¢«æ¾ç¤ºåºæ?¥ãè¿æ¯ç±äºè·¯ç±å¨é»è®¤æ¾ç¤ºâPublicâ?->âindex.htmlâ?æä»¶ãå?é?¢çæ¥éª¤å°ä¼æ´æ¹è·¯ç±éæ©ã
å¨â项ç®â?çªå?£ä¸æ©å±âPublicâ?ã
å?³é®ç¹å»âindex.htmlâ?èç¹ï¼ç¶å?å¨å¼¹åºè?å?ä¸éæ©âå é¤â?ã
å¨â项ç®â?çªå?£ä¸æ©å±âé
?ç½®â?èç¹ï¼å?å»âroutes.rbâ?ï¼å°å
¶å¨ç¼è¾å¨ä¸æå¼ã
æ¥æ¾ä»¥ä¸æ³¨éï¼
# map.connect '', :controller => "welcome"
使ç¨å¦ä¸ç²ä½æç¤ºç代ç ?æ¿æ?¢è¯¥æ³¨éã
代ç ?ç¤ºä¾ 10ï¼è·¯ç±éæ©ä»£ç ?
# You can have the root of your site routed by hooking up ''
# -- just remember to delete public/index.html.
map.connect '', :controller => "item"
为äºç¡®ä¿?è·¯ç±éæ©çæ¹å¨è½è¢«æ?å¡å¨æéç¨ï¼ç¹å» IDE å?³ä¸è§çæ?å¡å¨å?æ¢æé®ï¼å¦ä¸å¾æç¤ºã
å¾ 16ï¼æ?å¡å¨å?æ¢æé®
ç¹å»âè¿?è¡ä¸»é¡¹ç®â?以卿µ?è§å¨ä¸å?¯å¨åºç¨ç¨åº?ã
ç»ä¹ æå¦ç¥è¯
ç°å¨è¯ç?ä»å¤´å¼å§æå»ºä¸ä¸ªé¡¹ç®ãå建ä¸ä¸ª Ruby on Rails 项ç®è½å¨ä»»å¡åè¡¨ä¸æ¾ç¤ºæ?¡ç®ã
å?¯ä»¥å?èä¸ JRuby ä¸èµ·ä½¿ç¨æ°æ?®åº å 10 åéå建 Ruby Weblog ã
è¥ä½¿ç¨æ°æ?®åºè¡¨ä»£æ¿æä»¶ï¼é£ææ ·æ?¥æå»ºä»»å¡å表åºç¨ç¨åº?å¢ï¼
æ´å¤ä¿¡æ?¯
å?è§? NetBeans Ruby ææ¡£ç´¢å¼ ï¼è·å?è§é¢æ¼ç¤ºåæç¨ã
Ruby on Rails web ç«ç¹å
å?«ä¸°å¯çè§é¢ã?å±ç¤ºã?æç¨ã?å?示ä¾å
容ã
å?¯ä»¥ä½¿ç¨âæ?ä»¶â?å·¥å
·ä¸è½½åå®è£
Ruby Depot æ ·ä¾åºç¨ç¨åº?ï¼å?¯è½æ¨æä½¿ç¨ç IDE çæ¬å·²ç»?å°å
¶å®è£
äºï¼ãæ?ä»¶å®è£
å?ï¼å¨â项ç®â?çªå?£ä¸å?å»é¼ æ å?³é®ï¼å¨å¼¹åºè?å?ä¸éæ©âæ°å»ºé¡¹ç®â?ãæ©å±âç±»å«â?é?¢æ?¿ä¸âæ ·ä¾â?èç¹ï¼éä¸âRubyâ?ãéæ©âDepotâ?ï¼å¹¶ç¹å»âä¸ä¸æ¥â?ãç¹å»â宿?â?ï¼å¹¶é?µç
§æµ?è§å¨ä¸ææ¾ç¤ºçèªè¿°æä»¶ï¼READMEï¼ä¸ç»åºçæå¯¼è¯´æã
æ£å¦æ¨æçæµç JRuby Interactive Rubyï¼IRBï¼æ§å¶å?°æ¯ä¸ä¸ªè½è®©æ¨äº¤äºè¾å
¥ Ruby è¯å?¥ç模å?ï¼ä¸ä½¿ç¨ Ruby IRB æå?ç䏿 ·ãæ¤å¤ï¼JRuby Interactive Rubyï¼IRBï¼æ§å¶å?°è¿æ??ä¾äºä¸ Java å¹³å?°åºç¨ç¨åº?ä¹é´çäºæ?使§ã
å?¯å¨ä¸»è?å?ä¸éæ©âçªå?£â?->âå
¶ä»â?->âRuby Shell (IRB)â?æ?¥æå¼æ§å¶å?°ãæ§å¶å?°ä¼å¨ IDE çä¸é¨åºç°ï¼å¦ä¸å¾æç¤ºã
å¾ 17ï¼JRuby IRB æ§å¶å?°
IRB æ§å¶å?°æ¯ä» NetBeans å®è£
æä»¶å¤¹ä¸å?¯å¨çãè¦?åæ?¢è³å?¦ä¸ä¸ªæä»¶å¤¹ï¼é®å
¥å¦ä¸å½ä»¤ï¼å° your-path æ¿æ?¢æ?æå?å
å?« Ruby æä»¶çæä»¶å¤¹çè·¯å¾ã
=> Dir.chdir("your-path ")
å
³éâæ§å¶å?°â?çªå?£ä¸?ä¼å?æ¢ IRB ä¼è¯?ã彿¨é?æ°æå¼è¯¥çªå?£ï¼å½ä»¤åå?²è®°å½ä¼ä¾?ç¶æ¾ç¤ºã è¦?å?æ¢ä¼è¯?ï¼å¨æ§å¶å?°ä¸é®å
¥ quit æè
exitã
è¯è¯ç
å¨ä¸»è?å?ä¸ï¼éæ©âçªå?£â?->âå
¶ä»â?->âRuby Shell (IRB)â?æ?¥æå¼ IRB æ§å¶å?°ã
é®å
¥ä¸äº Ruby 常é?æ?¥çæä¸ä¸ç¯å¢ï¼ä¾å¦ PLATFORM ã?VERSION ã?ENV_JAVA ã?ENV ãé®å
¥ Object::contants æ?¥æ¥çææé¡¶çº§å¸¸é?ã
ä½¿ç¨ IRB è¯ç¨ Ruby è¯å?¥ä¾å¦ï¼é®å
¥ä¸åè¯å?¥ï¼çä¸ä¸ Ruby 伿ä»ä¹æ ·çè¾åºï¼
>> String.ancestors
>> "fig mango orange melon grapes".split(pattern="\s")
>> "users@ruby.netbeans.org" =~ /\A[\w\._%-]+@[\w\.-]+\.[a-zA-Z]{2,4}\z/
è¯ç?æ³æ³å
¶ä»æ¨å?¯è½æ³è¦?è¯éªç Ruby è¯å?¥ï¼æ¯å¦æ¥çæåºå¼å¸¸çç±»åã
ä½éªä¸ä¸ä»£ç ?è¡¥å
¨å¼¹åºè?å?çç¹æ§ãé®å
¥æå?å 个å符ï¼ç¶å?æä¸âTabâ?é®ï¼å?¯ä»¥çå°ä¸ä¸ªå»ºè®®å表ï¼å¦ä¸å¾æç¤ºãæ¨å?¯ä»¥ç»§ç»è¾å
¥ï¼ä»¥ç¼©ç该å表ã éæ©æééé¡¹ï¼æä¸âEnterâ?é®ã
å¾ 18ï¼ä»£ç ?è¡¥å
¨å¼¹åºè?å?
æå ä¸âå?ä¸ç®å¤´â?æ»å¨å½ä»¤åå?²è®°å½ï¼ç¶å?æâå?ä¸ç®å¤´â?å?䏿»å¨ãæä¸âEnterâ?é®ï¼é?æ°æ§è¡ä¸æ?¡å½ä»¤ã
æ´å¤ä¿¡æ?¯
>> æ´å¤ Ruby ææ¡£