端午放假的这几天,由于无聊,我又看了看ruby。
但是还是没有搞懂关于其block和closure。
今天,我看到了一篇对ruby创始人的采访,看到了一句很关键的话:real closure。
什么意思呢?不是拷贝而是直接的共享!
于是,我明白了。
下边的程序可以加深理解:
于是,事情就很清楚了:
1,block运行在定义它的环境中
2,block可以使用定义它时的环境,包括局部变量,self之类的东西
3,block可以接受参数,就像方法接受参数一样
4,不要对block的参数赋值,那样会产生一个新的在block之中的局部变量
5,你当然可以调用block的参数的方法(every thing is object!)
6,如果是单线程的,对block的定义和使用两个环境是交错执行的,特别的是创建block的环境可能被改变,但是这没有问题,你在这里创建的block,是你要改的,没有问题,只是调用的时机有所改变。
7,如果是多线程,情况略微复杂,比方说,我让两个线程同时运行mycat.miao,那么good中的a就可能被不同线程改变,有可能产生冲突。这种情况我没试,不过,我觉得已经没什么问题。
8,一个重要的思想是,ruby很大程度上仿照lisp,这给我指引了方向,从某些方面上讲,ruby's block有点像scheme的call/cc,只是一点点。
总之,知道了ruby的block和closure是很重要的,我觉得就这一点才是ruby的独特之处,其他的都没什么稀奇的。这好像略微改变得了对象之间的交互方式,当然只是外在的。原因就是closure的存在——一段代码,还有对环境的引用。这就是ruby的独特之处。
但是还是没有搞懂关于其block和closure。
今天,我看到了一篇对ruby创始人的采访,看到了一句很关键的话:real closure。
什么意思呢?不是拷贝而是直接的共享!
于是,我明白了。
下边的程序可以加深理解:
#my ruby play
$a=1
class Cat
def miao
a=Dog.new
yield(a)
a.hello
puts "dkdkdkdkdk"
end
end
class Dog
def initialize
@name="snoopy"
end
def bark
puts @name
end
end
def good
a=2
mycat=Cat.new
my=Proc.new do |mm|
class << mm
def hello
puts "hello"
end
end
mm.bark
#a=a*mm
end
mycat.miao(&my)
puts "first change:#{a}!"
mycat.miao(&my)
puts "second change:#{a}!"
puts "ok!!!!!"
end
#gogo!
good()
于是,事情就很清楚了:
1,block运行在定义它的环境中
2,block可以使用定义它时的环境,包括局部变量,self之类的东西
3,block可以接受参数,就像方法接受参数一样
4,不要对block的参数赋值,那样会产生一个新的在block之中的局部变量
5,你当然可以调用block的参数的方法(every thing is object!)
6,如果是单线程的,对block的定义和使用两个环境是交错执行的,特别的是创建block的环境可能被改变,但是这没有问题,你在这里创建的block,是你要改的,没有问题,只是调用的时机有所改变。
7,如果是多线程,情况略微复杂,比方说,我让两个线程同时运行mycat.miao,那么good中的a就可能被不同线程改变,有可能产生冲突。这种情况我没试,不过,我觉得已经没什么问题。
8,一个重要的思想是,ruby很大程度上仿照lisp,这给我指引了方向,从某些方面上讲,ruby's block有点像scheme的call/cc,只是一点点。
总之,知道了ruby的block和closure是很重要的,我觉得就这一点才是ruby的独特之处,其他的都没什么稀奇的。这好像略微改变得了对象之间的交互方式,当然只是外在的。原因就是closure的存在——一段代码,还有对环境的引用。这就是ruby的独特之处。