友链
导航
These are the good times in your life,
so put on a smile and it'll be alright
友链
导航
ri keyword
查看n = 100 r = rand(10) + 1 g = 0 puts "I have a number between 1 .. #{n}" until g == r g = gets().to_i if g > r puts 'too big' elsif g < r puts 'too small' end end puts 'bingo'
(1..10).each { |i| puts i }
class Tree attr_accessor :children, :node_name def initialize(name, children = []) @children = children @node_name = name end def visit_all(&block) visit &block children.each { |c| c.visit_all &block } end def visit(&block) block.call self end def to_s s = "visiting entire tree\n" self.visit_all { |node| s += "#{node.node_name}\n" } s end end ruby_tree = Tree.new( 'Ruby', [Tree.new('Reia'), Tree.new('MacRuby')] ) puts 'Visiting a node' ruby_tree.visit { |node| puts node.node_name } puts puts 'visiting entire tree' ruby_tree.visit_all { |node| puts node.node_name }
class Numeric def inches self end def feet self * 12.inches end def yards self * 3.feet end def miles self * 5280.feet end def back self * -1 end def forward self end end puts 10.miles.back puts 2.feet.forward
module ToFile def filename "object_#{self.object_id}.txt" end def to_f File.open(filename, 'w') { |f| f.write(to_s) } end end class Person include ToFile attr_accessor :name def initialize(name) @name = name end def to_s name end end Person.new('Xiaopei').to_f
class Roman def self.method_missing name, *args puts '===' puts name roman = name.to_s roman.gsub!('IV', 'IIII') roman.gsub!('IX', 'VIII') roman.gsub!('XL', 'XXXX') roman.gsub!('XC', 'LXXX') puts roman (roman.count('I') + roman.count('V') * 5 + roman.count('X') * 10 + roman.count('L') * 50 + roman.count('C') * 100) end end puts Roman.X puts Roman.XC puts Roman.XII puts Roman.X
module ActsAsCsv def self.included(base) # Ruby will invoke the included method whenever # this module gets included into another # Object.extend: # Adds to obj the instance methods from each module # given as a parameter. base.extend ClassMethods end module ClassMethods def acts_as_csv include InstanceMethods end end module InstanceMethods def read @csv_contents = [] filename = self.class.to_s.downcase + '.txt' file = File.new(filename) @headers = file.gets.chomp.split(', ') file.each do |row| @csv_contents << row.chomp.split(', ') end end attr_accessor :headers, :csv_contents def initialize read end def each(&block) self.csv_contents.each do |row| yield CsvRow.new(@headers, row) end end end end class CsvRow def initialize(headers, values) @hash = Hash.new headers.each_index do |i| @hash[headers[i]] = values[i] end end def to_s @hash.to_s end def method_missing name, *args # name 默认是 symbol, 需 to_s @hash[name.to_s] end end class RubyCsv # no inheritance! You can mix it in include ActsAsCsv include ActsAsCsv acts_as_csv end m = RubyCsv.new puts m.headers.inspect puts m.csv_contents.inspect # 可配套 rubycsv.txt 使用 # ruby, php # puts, echo # def, define # 其实上面的 module 和 class 的定义在目前功能下, 和下面的相等 module ActsAsCsv def read @csv_contents = [] filename = self.class.to_s.downcase + '.txt' file = File.new(filename) @headers = file.gets.chomp.split(', ') file.each do |row| @csv_contents << row.chomp.split(', ') end end attr_accessor :headers, :csv_contents def initialize read end end class RubyCsv # no inheritance! You can mix it in include ActsAsCsv include ActsAsCsv end
sum = 1 + 2 a, b = 1, 2 1 > 2 ? true : false; puts 'Hi' [1, 2, 3].each { |e| puts e } e = M * c**2 # No spaces after (, [ or before ], ). some(arg).other [1, 2, 3].length
def some_method data = initialize(options) data.manipulate! data.result end def some_method result end
# Limit lines to 80 characters. def send_mail(source) Mailer.deliver(to: 'bob@example.com', from: 'us@example.com', subject: 'Important message', body: source.text) end # good num = 1_000_000
def some_method # body omitted end def some_method_with_arguments(arg1, arg2) # body omitted end
# good if some_condition # body omitted end # Don't use parentheses around the condition of an if/unless/while, unless the **condition contains an assignment** if (x = self.next_value) # body omitted end # but it's still bad. Don't use the return value of = (an assignment) in conditional expressions. x = self.next_value if x # body omitted end
?:
), Use one expression per branch in a ternary operator, inline onlyresult = some_condition ? something : something_else if some_condition nested_condition ? nested_something : nested_something_else else something_else end
?:
without :
)# good do_something if some_condition # another good option some_condition and do_something
unless
over if for negative conditions (or control flow or
). And always positive case first(Never use unless with else).# good do_something unless some_condition # another good option some_condition or do_something
case when song.name == 'Misty' puts 'Not again!' when song.duration > 120 puts 'Too long!' when Time.now.hour > 21 puts "It's too late" else song.play end kind = case year when 1850..1889 then 'Blues' when 1890..1909 then 'Ragtime' when 1910..1929 then 'New Orleans Jazz' when 1930..1939 then 'Swing' when 1940..1950 then 'Bebop' else 'Jazz' end
arr = [1, 2, 3] # good arr.each { |elem| puts elem }
loop do puts val val += 1 break unless val < 0 end
do_something while some_condition do_something until some_condition
class Person attr_reader :name, :age # omitted end temperance = Person.new('Temperance', 30) temperance.name puts temperance.age x = Math.sin(y) array.delete(e)
# good def some_method(some_arr) some_arr.size # no return end
f((3 + 2) + 1)
.# good def ready? if last_reviewed_at > last_updated_at # self omitted worker.update(content, options) self.status = :in_progress end status == :verified end
class Foo attr_accessor :options # ok def initialize(options) self.options = options # both options and self.options are equivalent here end # bad def do_something(options = {}) unless options[:when] == :later output(self.options[:message]) end end # good def do_something(params = {}) unless params[:when] == :later output(options[:message]) end end end
# set name to Bozhidar, only if it's nil or false name ||= 'Bozhidar' # bad - would set enabled to true even if it was false enabled ||= true # good enabled = true if enabled.nil?
# good lambda = ->(a, b) { a + b } lambda.(1, 2)
{ … }
for single-line blocks.names = ['Bozhidar', 'Steve', 'Sarah'] # good names.each { |name| puts name } # good names.select { |name| name.start_with?('S') }.map { |name| name.upcase }
do…end
for multi-line blocks._
for unused block parameters.# good result = hash.map { |_, v| v + 1 }
begin fail 'Oops'; rescue => error raise if error.message != 'Oops' end
详见文档, 这里记几条容易忘的规则:
> puts 'This appears to be true.' if x == 4 This appears to be true. => nil > x = x + 1 while x < 10 => nil > x => 10
'[BOLD]Strategy[\BOLD]'.gsub(/\[BOLD\](.*?)\[\\BOLD\]/, '<em>\\1</em>' #=> <em>Strategy</em>
功能 | 命令 |
---|---|
查看当前源 | gem source |
删除源 | gem source -r http://rubygems.org/ |
增加源 | gem source -a http://ruby.taobao.org |
Installation | gem install mygem |
Uninstallation | gem uninstall mygem |
Listing installed gems | gem list - -local |
Listing available gems | gem list - -remote |
Create RDoc documentation for all gems | gem rdoc - -all |
Download but do not install a gem | gem fetch mygem |
Search available gems | gem search STRING - -remote |
Ruby 自 1.9 起加入了 json, 之前需要额外安装(apt-get install ruby-json
). Ruby 更推荐的格式是 yaml. 而 php 需装扩展才能支持 yaml.
# encode data = { name: 'dave', address: [ 'tx', 'usa' ], age: 17 } serialized = data.to_json serialized # => {"name":"dave","address":["tx","usa"],"age":17} File.open("data", "w") {|f| f.puts serialized} # decode serialized = File.read("data") data = JSON.parse(serialized) data # => {"name"=>"dave", "address"=>["tx", "usa"], "age"=>17} # j 和 jj 分别是普通和美化输出 json 的方法
可使用 `
或 %x
( 区别?):
`date` # => "Mon Apr 13 13:25:58 CDT 2009\n" `ls`.split[34] # => "ext_c_win32ole.tip" %x{echo "Hello there"} # => "Hello there\n"