1.Proc
irb(main):001:0> a,b = [1,2,3], [4,5]
=> [[1, 2, 3], [4, 5]]
irb(main):002:0> aum = Proc.new {|total,x| total+x }
=> #<Proc:0x36d047@(irb):2>
irb(main):003:0> sum = a.inject(0, &aum)
=> 6
闭包是指未绑定到任何对象的自由代码,闭包中的代码与任何对象和全局变量无关,只与执行此段代码的上下文相关。Ruby中的闭包实现有:Block,Proc,Lambada。Proc是函数化的block。Proc的作用是将Block函数化,提高Block的重复使用性。如例子所示在需要使用Block的时候使用&aum调用即可。
(1)Proc创建
irb(main):002:0> aum = Proc.new {|total,x| total+x }
(2)Proc调用
irb(main):026:0> aum = Proc.new {|total,x| total+x }
=> #<Proc:0x116318b@(irb):26>
irb(main):027:0> aum[1,2]
=> 3
irb(main):028:0> aum.arity
=> 2
其中的arity是Proc和Lambda特有的方法,判断Proc和Lambda期待的参数数目。
(3)Proc的相等性
Proc使用==判断两个Proc是否相等,并非使用同样的方法block就是相等的,只有clone或duplicate时==才返回true。
irb(main):029:0> aum = Proc.new {|total,x| total+x }
=> #<Proc:0x8c7be5@(irb):29>
irb(main):030:0> aum_1 = aum.clone
=> #<Proc:0x8c7be5@(irb):29>
irb(main):031:0> aum_1 == aum
=> true
irb(main):032:0> aum_1.object_id == aum.object_id
=> false
2.p,print,puts的区别:
p 不识别转义字符,完全打印
puts 识别转义字符,自动换行
print 识别转义字符,不自动换行
irb(main):023:0> p "hello,\n world","tom"
"hello,\n world"
"tom"
=> nil
irb(main):024:0> puts "hello,\n world","tom"
hello,
world
tom
=> nil
irb(main):025:0> print "hello,\n world","tom"
hello,
worldtom=> nil
irb(main):026:0>
3.数组
(1)数组元素的类型不是不变得;
(2)数组长度 length 或者size;
(3)使用%W(默认每个以空格隔开的元素以双引号包围) 和%w(以单引号包围) 可以表示字符串数组(ruby的版本不同而有所变化);
(4)数组引入了简易的数组拼接方法
---arr_a|arr_b:将两个数组中的所有元素合并,去除重复字符
---arr_a&arr_b:将两个数组中相同元素取出,并去除其中的重复字符
以上的数组方法并不会对元素进行排序处理
(5)对数组元素的排序
升序
irb(main):028:0> arr = [12,11,34,2,4,0]
=> [12, 11, 34, 2, 4, 0]
irb(main):029:0> arr.sort!
=> [0, 2, 4, 11, 12, 34]
降序
irb(main):030:0> arr.sort! {|x,y| y<=>x}
=> [34, 12, 11, 4, 2, 0]
4.Hash
ruby支持两种创建hash方式
irb(main):032:0> hash_1 = {"one" => 1, "two" => 2}
=> {"one"=>1, "two"=>2}
irb(main):033:0> hash_2 = {:one => 1}
=> {:one=>1}
后者比前者的效率高
此外,可以通过多种方式从数组生成hash
def p_hash_from_arr_method1(arr)
Hash[*arr]
end
def p_hash_from_arr_method2(arr)
Hash[*arr.flatten]
end
arr_4_method1 = %w[we are ch ha]
arr_4_method2 = [[1,"a"],[2,"b"]]
p p_hash_from_arr_method1(arr_4_method1), p_hash_from_arr_method2(arr_4_method2)
结果:
{"we"=>"are", "ch"=>"ha"}
{1=>"a", 2=>"b"}
但是在ruby1.9种似乎已经不支持从数组生成hash了,具体的调查ing。。。
5.序列
irb(main):038:0> range_1 = 1...4
=> 1...4
irb(main):039:0> num = 1.9
=> 1.9
irb(main):041:0> range_1.include? num
=> true
5.false
在条件判断中nil和false是不成立,其他的均为成立,但是nil和false并不是等价的
6.判断某个对象是否支持某个方法
irb(main):050:0> arr = Array.new
=> []
irb(main):051:0> arr.respond_to? :"sort!"
=> true
7.equal,==,object_id
equal用于比较两个对象是否是对同一个对象的引用,object_id具有同样功能。==是对两个对象的值的比较。
irb(main):001:0> arr = Array.new
=> []
irb(main):002:0> arr_1 = Array.new
=> []
irb(main):003:0> arr_2 = Array.new
=> []
irb(main):004:0> arr_3 = arr_1
=> []
irb(main):005:0> arr_1.equal?(arr_2)
=> false
irb(main):006:0> arr_1.equal?(arr_3)
=> true
irb(main):007:0> arr_1.object_id == arr_2.object_id
=> false
irb(main):008:0> arr_1.object_id == arr_3.object_id
=> true
8.修改常量的值
试图给常量赋值时,ruby发出警告,但是常量的值还是被修正。
irb(main):009:0> HEIGHT = 12
=> 12
irb(main):010:0> HEIGHT = 1
(irb):10 warning: already initialized constant HEIGHT
=> 1
irb(main):011:0> p HEIGHT
1
=> nil
irb(main):012:0>
9.赋值
左值和右值得数量不同:
1.左边的数量大于右边:最后的变量被赋值nil
2.左边的数量小于右边,右边多余的值不会付给任何变量
irb(main):001:0> a,b,c = 1,2
=> [1, 2]
irb(main):002:0> p a
1
=> nil
irb(main):003:0> p b
2
=> nil
irb(main):004:0> p c
nil
=> nil
irb(main):005:0> a,b = "a","b","c"
=> ["a", "b", "c"]
irb(main):006:0> p a
"a"
=> nil
irb(main):007:0> p b
"b"
=> nil
10.defined?
没有定义的返回nil
irb(main):003:0> arr = Array.new()
=> []
irb(main):004:0> defined? arr
=> "local-variable(in-block)"
irb(main):005:0> defined? a
=> nil
irb(main):006:0>
11.单例模式
irb(main):015:0> class Test
irb(main):016:1> include Singleton
irb(main):017:1> def say(val)
irb(main):018:2> p val
irb(main):019:2> end
irb(main):020:1> end
=> nil
irb(main):021:0> test = Test.instance()
=> #<Test:0xe555bd>
irb(main):022:0> test.say("tom")
"tom"
12.模块
module是不支持实例和子类继承的。可以通过以下方式来调用module方法:
(1)
irb(main):051:0> module MM
irb(main):052:1> def self.say
irb(main):053:2> p "hello"
irb(main):054:2> end
irb(main):055:1> end
=> nil
irb(main):056:0> MM.say
"hello"
=> nil
(2)
irb(main):001:0> module M
irb(main):002:1> def say
irb(main):003:2> p "hello"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> class ModuleTest
irb(main):007:1> include M
irb(main):008:1> end
=> ModuleTest
irb(main):009:0> moduletest = ModuleTest.new
=> #<ModuleTest:0x775121>
irb(main):010:0> moduletest.say
"hello"
=> nil
irb(main):011:0>
13.ruby重写和重载讨论
重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同。
irb(main):025:0> class Shape
irb(main):026:1> def print_infor(width)
irb(main):027:2> p width
irb(main):028:2> end
irb(main):029:1> def print_infor(width,length)
irb(main):030:2> p width,length
irb(main):031:2> end
irb(main):032:1> end
=> nil
irb(main):033:0> shape.print_infor(1)
ArgumentError: wrong # of arguments(1 for 2)
from (irb):33:in `print_infor'
from (irb):33
irb(main):034:0> shape.print_infor(1,2)
1
2
=> nil
irb(main):035:0>
由此可见,ruby并不支持方法重载。
重写是子类的方法覆盖父类的方法,要求方法名和参数都相同。
irb(main):035:0> class Circle<Shape
irb(main):036:1> def print_infor(width,length)
irb(main):037:2> p "width,length",width,length
irb(main):038:2> end
irb(main):039:1> end
=> nil
irb(main):040:0> circle = Circle.new(1,2)
=> #<Circle:0x1aa0e3b @width=1, @length=2>
irb(main):041:0> circle.print_infor(1,2)
"width,length"
1
2
=> nil
ruby支持重写。