Skip to content

AHABHGK

Ruby

解释执行

无需声明变量

每条代码都有返回值

纯面向对象,“真一切皆为对象”

简洁的判断语句:order.calculate_tax unless order.nil?

鸭子类型

符号

1# :string 表示 symbol,:string.object_id == :string.object_id
2def tell_the_truth(options={})
3 if options[:profession] == :lawyer
4 'it could be believed that this is almost certainly not false.'
5 else
6 true
7 end
8end
9
10tell_the_truth
11# => true
12tell_the_truth :profession => :lawyer
13# => "it could be believed that this is almost certainly not false."
14a = {:profession => :lawyer, :string => 'hahha'} # 散列表
15tell_the_truth a
16# => "it could be believed that this is almost certainly not false."

代码块(匿名函数)

1animals = ['lions', 'tigers', 'bears', 'duck']
2animals.each {|a| puts a}
3# lions
4# tigers
5# bears
6# duck
7# => ["lions", "tigers", "bears", "duck"]

yield 代码块

1class Fixnum
2 def my_times
3 i = self
4 while i > 0
5 i = i - 1
6 yield
7 end
8 end
9end
10
113.my_times {puts 'mangy moose'}
12# mangy moose
13# mangy moose
14# mangy moose
15# => nil

&block 闭包

1def call_block(&block)
2 block.call
3end
4
5def pass_block(&block)
6 call_block(&block)
7end
8
9pass_block {puts 'helloo'}
10# helloo
11# => nil

14.class.superclass.superclass.superclass.superclass
2# Integer Numeric Object BasicObject nil
3
44.class.class.superclass.superclass.superclass.superclass
5# Integer Class Module Object BasicObject nil
1class Tree
2 attr_accessor :children, :node_name
3
4 def initialize(name, children = [])
5 @children = children
6 @node_name = name
7 end
8
9 def visit_all(&block)
10 visit &block
11 children.each {|c| c.visit_all &block}
12 end
13
14 def visit(&block)
15 block.call self
16 end
17end
18
19ruby_tree = Tree.new("Ruby", [Tree.new("Reia"), Tree.new("MacRuby")])
20ruby_tree.visit {|node| puts node.node_name}
21# Ruby
22ruby_tree.visit_all {|node| puts node.node_name}
23# Ruby
24# Reia
25# MacRuby

Mixin 多继承:Java 通过接口实现,Ruby 通过 Mixin,先定义类的主要部分,然后用模块添加额外功能

1module ToFile
2 def to_f
3 puts "mixin tofile"
4 end
5end
6
7class Person
8 include ToFile
9 attr_accessor :name
10
11 def initialize(name)
12 @name = name
13 end
14
15 def to_s
16 name
17 end
18end
19
20Person.new('matz').to_f
21# mixin tofile

可枚举(枚举模块):让类可枚举,必须实现 each

1a = [5, 2, 4, 3, 1]
2b = a.sort # [1, 2, 3, 4, 5]
3a.any? {|i| i > 4} # true
4a.all? {|i| i > 4} # false
5c = a.collect {|i| i * 2} # [10, 4, 6, 8, 2]
6d = a.select {|i| i % 2 == 0} # [2, 4]
7a.member?(2) # true
8a.inject(10) do |acc, cur|
9 puts "acc: #{acc}, cur: #{cur}"
10 acc + cur
11end
12# => 25

可比较(比较模块):让类可比较,必须实现 <=>

1'same' <=> 'same' # 0

元编程:写能写程序的程序

1# rails
2class Department < ActiveRecord::Base
3 has_many :employees
4 has_one :manager
5end

开放类:可以对类重新定义

1class NilClass
2 def blank?
3 true
4 end
5end
6
7class String
8 def blank?
9 self.size == 0
10 end
11end
12
13["", "person", nil].each do |e|
14 puts e unless e.blank?
15end
16# "person"

method_missing:找不到默方法时调用,可以复写 method_missing 方法

1class Roman
2 def self.method_missing name, *args
3 roman = name.to_s
4 roman.gsub("IV", "IIII")
5 roman.gsub("IX", "VIIII")
6 roman.gsub("XL", "XXXX")
7 roman.gsub("XC", "LXXXX")
8
9 (roman.count("I") +
10 roman.count("V") * 5 +
11 roman.count("X") * 10 +
12 roman.count("L") * 50 +
13 roman.count("C") * 100)
14 end
15end
16
17puts Roman.XII # 12

动态的改变类:模块被另一模块包含,Ruby 就会调用该模块的 included 方法,类也是模块

feeling

自由(有点像 JS 中修改原型,但平时更多是限制的)