第二天学习继续,今天重点学习函数,数组和类等编程的基本要素。
def tell_me
puts true
end
def tell_me(a)
puts a
end
tell_me 1
1
=> nil
同样可以指定参数默认值:
def tell_me(a=‘1‘,b)
puts a
puts b
end
=> nil
tell_me 2
1
2
=> nil
tell_me 3,4
3
4
=> nil
我们看到指定默认值的方式跟其他语言类似。
有些苦恼的是,看起来我们需要记住每一个函数的参数数量和含义。
Ruby同样支持可变参数,而且因为不受类型的限制,使用相当自由:
def test(*tt)
for i in 0...tt.length
puts tt[i]
end
end
=> nil
test 1,2
1
2
=> 0...2
test ‘a‘
a
=> 0...1
def give_me
true
end
=> nil
i=give_me
=> true
i
=> true
这个函数我们并没有指定返回值,但是函数还是返回了最后执行的语句true的值。
$ irb
def test
a=1
b=2
return a,b
end
=> nil
var=test
=> [1, 2]
var.class
=> Array
var
=> [1, 2]
Ruby可以通过return语句指定返回值,而且跟C家族语言不同的是,Ruby可以同时返回多个返回值。
因为动态语言的特性,Ruby看起来如此自由,但是看起来这就更要求调用者对他们的调用负责。
代码块是没有名字的函数。
3.times{puts ‘hi‘}
3.times do
puts ‘hello‘
end
昨天在区间一节中提到的each函数后面其实也是代码块:
names=[‘lee‘,‘tom‘,‘jim‘]
names.each{|a| puts a}
下面我们来看下自定义的方法来执行代码块:
def my_times(i=5)
while i>0
i=i-1
yield
end
end
my_times(3){puts ‘a‘}
我们看到这个函数根据传入参数,调用了一定数量的代码块。
- 函数中定义的yield表示执行代码块中的代码。
我们也可以将代码块作为参数一直传递下去。
def call_block(&block)
block.call
end
def pass_block(&block)
call_block(&block)
end
pass_block{puts ‘hello‘}
animals = [‘lions‘, ‘tigers‘, ‘bears‘]
puts animals[1]
puts animals[-1]
puts animals[0..1]
irb(main):002:0> [].class
=> Array
irb(main):003:0> a =[]
=> []
irb(main):004:0> a[1]
=> nil
irb(main):005:0> b[1]
NameError: undefined local variable or method `b‘ for main:Object
from (irb):5
from /usr/bin/irb:12:in `<main>‘
irb(main):006:0> a[1] = 1
=> 1
irb(main):007:0> a[0] = ‘zero‘
=> "zero"
irb(main):009:0> a[2]=[‘2‘,‘3‘,[4,5]]
=> ["2", "3", [4, 5]]
irb(main):010:0> a
=> ["zero", 1, ["2", "3", [4, 5]]]
irb(main):011:0> a[2][2]
=> [4, 5]
irb(main):012:0> a[2][2][1]
=> 5
irb(main):021:0> a=[]
=> []
irb(main):022:0> a[1]=8
=> 8
irb(main):023:0> a[3]=6
=> 6
irb(main):024:0> a
=> [nil, 8, nil, 6]
比起大多数语言的数组,Ruby的数组使用很自由,从上面这些代码可以看出来。
irb(main):025:0> a.push(4)
=> [nil, 8, nil, 6, 4]
irb(main):026:0> a.pop
=> 4
irb(main):027:0> a
=> [nil, 8, nil, 6]
数组同样支持push和pop,栈顶位于数组尾部。
散列表就是键值对,对应java里面的map容器。
irb(main):032:0> map={1=>‘one‘,2=>‘two‘}
=> {1=>"one", 2=>"two"}
irb(main):033:0> map
=> {1=>"one", 2=>"two"}
irb(main):034:0> map[1]
=> "one"
irb(main):035:0> map[3]
=> nil
其实和数组类似,关键的不同就在于一个=>符号,符号前面是键,后面是值。
所有的类都有一个共同的祖先,BasicObject。
class TreeTest
attr_accessor :children,:node_name
def initialize(name,children=[])
@children = children
@node_name = name
end
end
ruby_tree = Tree.new("ruby",[Tree.new(‘1‘),Tree.new(‘2‘)])
上面代码定义了一个简单的类。
今天主要学习了Ruby的函数,类,数组的基本使用,最大的感触是Ruby的实现充满了符合直觉的特性,在掌握了基本语法后,很多代码只需要按照尝试着写就可以执行。
今天实践在前面Tree类的基础上加上遍历访问的功能:
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
end
ruby_tree = Tree.new("ruby",[Tree.new(‘1‘),Tree.new(‘2‘)])
ruby_tree.visit {|node| puts node.node_name}
ruby_tree.visit_all {|node| puts node.node_name}
visit方法传递了代码块,调用了代码块并用self做参数(所以看起来代码块是通过这种方式获得参数?),其实就是打印了调用实例的node_name。
visit_all先对当前节点调用了visit方法,然后对子节点进行了递归。
原文地址:http://blog.csdn.net/lee_3do/article/details/43981865