ruby学习中的问题
当前位置:首页 ----> Web开发 ----> Ruby/Python
关键词:ruby,Block,include,vars end end,initialize,proc,mats,object,variable,scope,module,mixin class
ajoo:
相关文章: X    module method/instance method需要怎样搞?  Closure & Block  每天一条Ruby小道之Symbol    <img src=http://www.javaeye.com/images/icon_more.gif/>          1。有attr_reader, attr_writer,很好。不过这个
def initialize(var1, var2, var3)
 @var1 = var1
 @var2 = var2
 @var3 = var3
end
也很烦阿。怎样标准库里面没有对这个东西的帮助函数?非要自己写一个然后include进来?这又何苦?
module Misc
 private
 def Object.ctor(*vars)
 define_method(:initialize) do |*params|
 vars.each_with_index do |var, i|
 instance_variable_set("@"+var.to_s, params[i])
 end
 end
 end
 def Object.decl_readable(*vars)
 attr_reader(*vars)
 ctor(*vars)
 end
 def Object.decl_mutable(*vars)
 attr_accessor(*vars)
 ctor(*vars)
 end
end
然后就可以不写讨厌的initialize,而写
class Person
 decl_readable :name, :age, :sex
end
2。proc和block的区别真的很别扭。proc不过是个优化了的,有一定限制的proc,这种优化细节还是藏起来的好。希望mats早点把这个修改过来。还我们一片everything is object的蓝天。 3。block的参数居然可以是instance variable。惊!甚至居然可以是外面scope定义好了的变量,虎躯剧震惊! 其实instance variable不可怕,毕竟这个'@'就可以很清楚地表明意图。就是这个局部变量比较吓人! 4。如布娃娃所说,只能mixin module,不能mixin class和object么?


buaawhl:
丫还虎躯 剧震惊! 不过,我等 ajoo fans 都已经看到了ajoo偶像的资料。确是180的虎躯。引用block的参数居然可以是instance variable。惊!甚至居然可以是外面scope定义好了的变量,虎躯剧震惊!Lisp, Perl都有这个dynamic scope吧。这不是很好?可以从外面注入block作为AOP Interceptor。打印个Log什麽的。只要有这个名字在就行。


ajoo:
这不是dynamic scope。 block parameter应当是形式参数。就像java的函数参数名字。 这个名字和外面scope的名字假如冲了,一般或用shadowing(java就是shadowing,虽然eclipse会警告),或报错。 象ruby这样默默地从了的,还是第一次看见。


buaawhl:
也不能说是ruby这样默默地从了,是现在的ruby IDE默默地从了,动态语言IDE 应当在静态语法分析上多下功夫。


ajoo:
您没明白。
x = 1
...
callcc do |x|
 ...
end

# surprise, x points to a continuation! 
要是象java那样是shadowing的效果,ide不警告也没什麽大不了的。但是现在,我不小心弄了一个变量重名(根据java以及很多其它语言的经验,应当不要紧的),它居然悄悄改变了我x变量的值。


buaawhl:
果然震惊。龙躯剧震惊。虽然,我没太看明白,但是这个# surprise, x points to a continuation! 确实显示了严重性。刚看了ajoo的contiunation article。代码遇到continuation,就要跳出去的(escape)。


armlinux-w:
引用2。proc和block的区别真的很别扭。proc不过是个优化了的,有一定限制的proc,这种优化细节还是藏起来的好。希望mats早点把这个修改过来。还我们一片everything is object的蓝天。 您这是什麽意思。 在我看来, proc 正是为了实现“ everythign is object ”才引入的。 不仅仅 thing 是对象,过程也是对象。 这是我对 proc 的理解。 block 和 proc 的区别,在于 block 更加 lightweight, 因此在很多场合用起来更方便,更少累赘。 我以为这个设计挺好的。为什么以为不好呢? 我倒是以为 lambda 和 Proc 之间的差别有点别扭, 请参见我在 Ruby for Rails 的译文: 不管如何,用 lambda 生成的 Proc 对象和用 Proc.new 生成的 Proc 对象之间是有差别的。这是一个微妙的差别,在某些时候,您需要意识到这个差别。这个差别与 return 关键字相关。lambda 中的 return 从 lambda 返回。而 Proc 中的 return 从外围方法(surrounding method)返回。


ajoo:
armlinux-w 写道 引用2。proc和block的区别真的很别扭。proc不过是个优化了的,有一定限制的proc,这种优化细节还是藏起来的好。希望mats早点把这个修改过来。还我们一片everything is object的蓝天。 您这是什麽意思。 在我看来, proc 正是为了实现“ everythign is object ”才引入的。 不仅仅 thing 是对象,过程也是对象。 这是我对 proc 的理解。 block 和 proc 的区别,在于 block 更加 lightweight, 因此在很多场合用起来更方便,更少累赘。 我以为这个设计挺好的。为什么以为不好呢? 我倒是以为 lambda 和 Proc 之间的差别有点别扭, 请参见我在 Ruby for Rails 的译文: 不管如何,用 lambda 生成的 Proc 对象和用 Proc.new 生成的 Proc 对象之间是有差别的。这是一个微妙的差别,在某些时候,您需要意识到这个差别。这个差别与 return 关键字相关。lambda 中的 return 从 lambda 返回。而 Proc 中的 return 从外围方法(surrounding method)返回。 block是不是lightweight,这是实现细节。实际上它的功能和proc一样的。一样的功能有两个东西,不爽。 至于说block的语法比proc方便,这是语法糖问题,和我说的无关。假如可能,我希望block/proc被统一起来,现在的block和proc语法可以自由使用。不要搞什麽"new Proc",不要搞什麽"&proc"这些古怪东西,{|x|...}这个block应当可以直接当作proc使用(置于系统内部是否要隐士作new Proc转换,应当解释器自己自动完成,我不关心)。


uncutstone:
ajoo 写道 block是不是lightweight,这是实现细节。实际上它的功能和proc一样的。一样的功能有两个东西,不爽。 至于说block的语法比proc方便,这是语法糖问题,和我说的无关。假如可能,我希望block/proc被统一起来,现在的block和proc语法可以自由使用。不要搞什麽"new Proc",不要搞什麽"&proc"这些古怪东西,{|x|...}这个block应当可以直接当作proc使用(置于系统内部是否要隐士作new Proc转换,应当解释器自己自动完成,我不关心)。 实际上,类似的功能有三个东西。 Proc, lambda, block。 block 和 Proc 的差别,我认为可以理解。 这其中的差别有点类似于单例类和普通类的差别。一个是无名的,一个有名的。 不过, Proc 和 lambda 的差别, 我比较困惑。


njmzhang:
貌似block和proc并不是相同的东西,proc除了包含block的code之外,还包含了local envrionment,它是一个closure


buaawhl:
其实,说了半天,这ruby啥的,语法就是不如jaskell语法好。http://www.javaeye.com/topic/13424清晰简单,要啥有啥,不多不少,恰到好处。天生FP,也支持OO。Object就是一个带有this的tuple。这Sun公司真是没有眼力,咋就把这个JRuby搜罗去了呢?Jaskell才是首选啊。


njmzhang:
Proc和lambda的区别比较微妙,您return的时候就知道了


ajoo:
重复ruby的tutorial没什麽意义。 block里面也可以引用environment里面的任何东西。只是说block没有被转换为object,不能到处传递而已。 其它的语言,就没有这种令人费解的分别,lisp/haskell只有lamda,groovy只有block。看看groovy的block,为什麽就是closure? ruby这个block vs proc也就是对没有lamda经验的人才不显得怪异。


uncutstone:
ajoo 写道 其它的语言,就没有这种令人费解的分别,lisp/haskell只有lamda,groovy只有block。看看groovy的block,为什麽就是closure? 因为它们不是 "everything is object”


uncutstone:
在我看来,某种意义上, block 代表 closure 的过程语义, Proc 代表 closure 的对象语义。


ajoo:
不解释了.懂得人自然懂.不懂的人我就不费劲了.


njmzhang:
ajoo 写道重复ruby的tutorial没什麽意义。 block里面也可以引用environment里面的任何东西。只是说block没有被转换为object,不能到处传递而已。 其它的语言,就没有这种令人费解的分别,lisp/haskell只有lamda,groovy只有block。看看groovy的block,为什麽就是closure? ruby这个block vs proc也就是对没有lamda经验的人才不显得怪异。 Ruby里block是syntax, 假如我只是想写a.each {...}, 那就不需要将block转化成object。假如将所有block转化成object,势必会影响效率,因为很多block用过之后就无须再用了。


ajoo:
njmzhang 写道ajoo 写道重复ruby的tutorial没什麽意义。 block里面也可以引用environment里面的任何东西。只是说block没有被转换为object,不能到处传递而已。 其它的语言,就没有这种令人费解的分别,lisp/haskell只有lamda,groovy只有block。看看groovy的block,为什麽就是closure? ruby这个block vs proc也就是对没有lamda经验的人才不显得怪异。 Ruby里block是syntax, 假如我只是想写a.each {...}, 那就不需要将block转化成object。假如将所有block转化成object,势必会影响效率,因为很多block用过之后就无须再用了。 对.当然是写a.each {...},而不是a.each(new Proc{...}) 我反对的是这个new Proc语法。而不是前者。 哪里需要new Proc? myproc = new Proc{...} 这个东西就比较别扭。为什麽不能: myproc = {...} 知道,需要把environment包裹在对象里嘛. 不过,这个包裹您解释器可以自己偷偷搞嘛。连java现在都知道要弄个auto-box来取悦客人了,ruby可是号称是千娇百媚,善解人意的头牌,干啥这么不识时务要麻烦程序员大爷我呢? 还有这个"&proc"语法,搞什麽?为什麽需要"&"这个特殊字符?ruby的method不是可以接受任意类型的对象做参数么?proc不是对象?别的对象,string啦,int啦,array啦,method啦,class啦,都不需要一个特殊的字符,proc为什麽这么特殊?


charon:
坚决支持ajoo同志!!!!!!! 在这一点上ruby显然不如python自洽.虽然python的作用域规则粗看之前不是很爽(需要显式指定作用域以及对全局变量赋值需要诡异的作法),但是毕竟能看到的就能看到,不能看到要费很大劲才能看到.lambda当作闭包的时候要传递外围变量,必须在参数列表中当作默认参数来搞,虽然丑陋了点,但安全. 而且, block这个东西太强大了,python的lambda只是一个表达式(以后会不会支持多行还不好说),ruby的block里面什麽都可以干。多写几行引入一些逻辑之后,测试怎样办?看起来不能方便的单独测试。


njmzhang:
myproc = {...}不行,有歧义,{...} 是定义literal hash的语法我一般不写myproc = new Proc{...},而是写myproc = lambda { |x| ...}lisp里您也写lambda单词吧, (lambda (x) ...)


uncutstone:
ajoo 写道 myproc = new Proc{...} 不过,这个包裹您解释器可以自己偷偷搞嘛。连java现在都知道要弄个auto-box来取悦客人了,ruby可是号称是千娇百媚,善解人意的头牌,干啥这么不识时务要麻烦程序员大爷我呢? 还有这个"&proc"语法,搞什麽?为什麽需要"&"这个特殊字符?ruby的method不是可以接受任意类型的对象做参数么?proc不是对象?别的对象,string啦,int啦,array啦,method啦,class啦,都不需要一个特殊的字符,proc为什麽这么特殊? 首先, myproc = new Proc{...} 是错误的写法, 正确的写法是 myproc = Proc.new{}. 理解 &proc , 其实很容易: & 其实和 c 中的 * 有点相似(当然还是有差别)。  c 中的 * 用于在指针和指针所指向的值之间来回转换, Ruby 中的& 用于在 Proc (对象) 和 block(过程)之间来回转换。 我以为很自然。 只是您没有理解 Proc 和 block 之间的差别, 您才以为别扭。


uncutstone:
ajoo 写道重复ruby的tutorial没什麽意义。 其它的语言,就没有这种令人费解的分别,lisp/haskell只有lamda,groovy只有block。看看groovy的block,为什麽就是closure? ruby这个block vs proc也就是对没有lamda经验的人才不显得怪异。 实际上, Ruby 的 closure 机制比 lisp 什麽的都更漂亮。 在 lisp 中, 您还需要使用关键字 lambda。 可是在 Ruby 中, 一个 block , 只需要使用{}包围, 不需要任何关键字。这更符合 closure 隐于无形的特性。closure, 本身就应当是 无色无味,无形无名。


ajoo:
njmzhang 写道myproc = {...}不行,有歧义,{...} 是定义literal hash的语法 我一般不写myproc = new Proc{...}, 而是写myproc = lambda { |x| ...} lisp里您也写lambda单词吧, (lambda (x) ...) 那么在调用method的时候,obj.f{...},parser是怎样区分这个{...}是block还是literal hash呢? 以为和myproc = {...}一样的难度把? 至于lisp,对亚。我需要写lamdbda。不过,区别在于,lisp只有一个lambda的概念,语法上虽然需要lambda关键字,语义上不象ruby这样同一个功能有两个概念实体。 要是ruby把{...}作为lambda{...}的语法糖,而不是孜孜不倦地说“block和proc不同”,那我没有意见。 另外一个问题是"&proc"这个语法,lisp/groovy/haskell中我可不需要搞这个古怪的冬冬。lambda/closure也不过就是一个普通变量/对象,不需要设计特殊规则。


cookoo:
ajoo 写道1。有attr_reader, attr_writer,很好。不过这个
def initialize(var1, var2, var3)
 @var1 = var1
 @var2 = var2
 @var3 = var3
end
这个一般是这么写的:
def initialize(var1, var2, var3)
 @var1, @var2, @var3 = var1, var2, var3
end
也不是太麻烦巴?


ajoo:
cookoo 写道ajoo 写道1。有attr_reader, attr_writer,很好。不过这个
def initialize(var1, var2, var3)
 @var1 = var1
 @var2 = var2
 @var3 = var3
end
这个一般是这么写的:
def initialize(var1, var2, var3)
 @var1, @var2, @var3 = var1, var2, var3
end
也不是太麻烦巴? var1,var2, var3重复了三遍啊。还不麻烦?要是您有很多model class要写,还是很希望能简化的。不是么?
decl_ctor :var1, :var2, :var3


ajoo:
关於这个"&"语法。不仅仅是理论上不自恰的问题。 这不,我在试图写一个decl_ctor来自动生成initialize函数:
class Person
 decl_ctor :name, :age, :sex
end
然后就可以调用Person.new 'tom', 10, :female 不过,这个代码生成对proc变量就不是那么爽。比如我有个Invoker class:
class Invoker
 def initialize(name, &callback)
 @name, @callback = name, callback
 end
 def invoke
 callback.call
 end
end
invoker = Invoker.new 'myinvoker', {10}
没问题。block可以被自动转换为Proc。 可是用decl_ctor就不成了,要出错,必须要用lambda函数显示转换:
class Invoker
 decl_ctor :name, :callback
 def invoke
 callback.call
 end
end
invoker = Invoker.new 'myinvoker', lambda {10}
别扭。


cookoo:
直接覆盖initialize方法很不灵活啊,要是intialize里除了初始化实例变量还想干些别的呢?要是需要传些可选参数进来呢?而且intialize的里instance_variable_set会绕过setter里可能的验证步骤,不安全呢。 假如要一边声明一边初始化可以用这样的代码:
class Object 
 def better_accessor(attrs) 
 (class << self; self; end).send :attr_accessor, *attrs.keys
 attrs.each {|k,v| instance_variable_set("@#{k}", v)}
 end 
end
然后就可以这样用:  'bar'
或先建对象后加属性,不用先定死值,但是用户可以在声明时绕过可能的setter验证,不安全:  'world'


uncutstone:
Ruby 中之所以有 Proc 和 block 的差别, 主要是由 Ruby 的一个基本哲学决定的: everything is object。 everything is object 意味着: 所有的变量和常量都是在引用某个对象。 但是 block 不是对象 。 这本身没有关系。因为 block 无名无形。 但是一旦您要用一个变量来引用这个 block 时,它必须转换为一个对象。 所以 Ruby 定义了一个 Proc, 用来表示 block 作为对象时的等价物。 而既然是对象, 它就要和其它对象一样, 有 new方法, 有类名等等。所以 Proc 有这些东西。 这里的关键是: block 不是对象, 它和 Ruby everyting is object 的哲学有一点不和谐。所以才有 Proc 这些机制。 在 lisp 这种语言中, 没有 everything is object 的要求,当然就没有这些问题。


ajoo:
cookoo 写道直接覆盖initialize方法很不灵活啊,要是intialize里除了初始化实例变量还想干些别的呢?要是需要传些可选参数进来呢?而且intialize的里instance_variable_set会绕过setter里可能的验证步骤,不安全呢。 假如要一边声明一边初始化可以用这样的代码:
class Object 
 def better_accessor(attrs) 
 (class << self; self; end).send :attr_accessor, *attrs.keys
 attrs.each {|k,v| instance_variable_set("@#{k}", v)}
 end 
end
然后就可以这样用:  'bar'
或先建对象后加属性,不用先定死值,但是用户可以在声明时绕过可能的setter验证,不安全:  'world'
不喜欢这样.我的目标还是不要绕过new。就用传统的ioc,从构造函数构造整个对象。 确实,无法作安全验证。不过,attr_writer也无法作安全验证,缺乏灵活性,对么?毕竟不是总需要那个灵活性的。在ioc设计的时候,也往往不需要在类内部作安全验证。 弄个decl_ctor, decl_readable, decl_mutable的目的就是对那80%甚至90%的情况节省代码。有时需要灵活性的时候,大可以自己直接写initialize。


cookoo:
block{...}只是do ... end的简写形式,假如把do end也当成对象和别的参数一样用逗号分割开传给方法未免有些怪异。。。 至于method和proc都是真正的对象,当然不需要&转换,直接call好了。 lambda好象是和Proc有重复且不协调,不知道为什麽,大概是历史遗留问题巴。。。 python的lambda就不要拿出来比了,有严重功能限制:只能返回一个值,不能包含更复杂的逻辑。比如: lambda k,y: b[k] = y
SyntaxError: can't assign to lambda


ajoo:
关於不能mixin一个object的问题。刚刚自己写了一个forward_message函数,以为也够用了。
 def Object.forward_message(obj, *symbols)
 symbols.each do |symbol|
 define_method(symbol) do |*params|
 obj.__send__(symbol, *params)
 end
 end
 end
然后就可以有选择地从任意一个对象(module, class, object都可以)有选择地mixin自己需要的method:
class MyClass
 forward_message MyHelperModule, :method1, :method2
end

MyClass.new.method1 //传递给MyHelperModule.method1
MyClass.new.method2 //传递给MyHelperModule.method2


cookoo:
ajoo 写道 不喜欢这样.我的目标还是不要绕过new。就用传统的ioc,从构造函数构造整个对象。 确实,无法作安全验证。不过,attr_writer也无法作安全验证,缺乏灵活性,对么?毕竟不是总需要那个灵活性的。在ioc设计的时候,也往往不需要在类内部作安全验证。 弄个decl_ctor, decl_readable, decl_mutable的目的就是对那80%甚至90%的情况节省代码。有时需要灵活性的时候,大可以自己直接写initialize。 是啊,helper嘛本来就是“帮得上的帮一下”,特殊需求当然自己写啦。 原来您在设计IoC,需求好恐怖阿,连每个方法都要传proc进去动态生成?


ajoo:
cookoo 写道ajoo 写道 不喜欢这样.我的目标还是不要绕过new。就用传统的ioc,从构造函数构造整个对象。 确实,无法作安全验证。不过,attr_writer也无法作安全验证,缺乏灵活性,对么?毕竟不是总需要那个灵活性的。在ioc设计的时候,也往往不需要在类内部作安全验证。 弄个decl_ctor, decl_readable, decl_mutable的目的就是对那80%甚至90%的情况节省代码。有时需要灵活性的时候,大可以自己直接写initialize。 是啊,helper嘛本来就是“帮得上的帮一下”,特殊需求当然自己写啦。 原来您在设计IoC,需求好恐怖阿,连每个方法都要传proc进去动态生成? 不是ioc容器。是ioc设计。也就是说:所有的依赖直接从外界通过构造函数获得。ioc设计可能是世界上最简单的代码了。


cookoo:
ajoo 写道关於不能mixin一个object的问题。刚刚自己写了一个forward_message函数,以为也够用了。。。 我刚才又翻了一下PickAxe, 其实内置库里已经有完整的delegate到另一个类或对象的办法了:您可以看一下p646的DelegateClass和SimpleDelegator,这两个会完全导入所有方法并保持原名字,或用p659的Forwardable和SingleForwardable精细控制哪些方法需要delegate并指定alias。


cookoo:
ajoo 写道您没明白。
x = 1
...
callcc do |x|
 ...
end

# surprise, x points to a continuation! 
要是象java那样是shadowing的效果,ide不警告也没什麽大不了的。但是现在,我不小心弄了一个变量重名(根据java以及很多其它语言的经验,应当不要紧的),它居然悄悄改变了我x变量的值。 这确实是目前ruby版本的一个问题,在ruby1.9中已被修正,会产生warning: shadowing outer local variable BTW. 这帖子内容丰富,我想改投精华了,怎样办啊Robbin?


njmzhang:
ajoo 写道 至于lisp,对亚。我需要写lamdbda。不过,区别在于,lisp只有一个lambda的概念,语法上虽然需要lambda关键字,语义上不象ruby这样同一个功能有两个概念实体。 要是ruby把{...}作为lambda{...}的语法糖,而不是孜孜不倦地说“block和proc不同”,那我没有意见。 另外一个问题是"&proc"这个语法,lisp/groovy/haskell中我可不需要搞这个古怪的冬冬。lambda/closure也不过就是一个普通变量/对象,不需要设计特殊规则。 lisp里也不是只有一个lambda,还有if这样的special form &proc实际上就是帮您做了Proc.new()这一操作,这个大概就是syntax suger,假如您已经传的已经是一个Proc对象了,当然不需要用&符号。 Proc在Ruby里应当看作是一种补充,为了实现某些FP style。 因为在Ruby里没有function这种对象,用def定义的function都是类的方法,必须要bind。要实现那种游离的function,就只有靠Proc。 大多数情况下,只需要用yield就可以了,您当做Proc不存在就好了,设计类库时也无须多引入一个参数,试比较:
def funcall1(f)
 f.call
end

def funcall2
 yield
end
还有一个原因应当让您用block而不用Proc, yield一个block比生成一个Proc(不管是用lambda还是&)再call它效率要高:
$ cat b1.rb
def funcall1(&p)
 p.call
end
i = 1
while i<500000
 funcall1 { 1 }
 i += 1
end

$ cat b2.rb
def funcall2
 yield
end
i = 1
while i<500000
 funcall2 { 1 }
 i += 1
end
您可以time一下两个程序的时间


ajoo:
晕阿。 好多人都说什麽block效率高云云。拜托,这是实现细节好不好? 假如不区分block/proc就不能达到这个效率了?解释器不会做点优化?只要保证执行的时候不到不得已不创建Proc对象不就完了? myproc = {|x|...} # 解释器内部作new Proc转换 call_method_with_block {|x|...} # 直接调用block,不用转换 call_method_with_block myproc # 假如解释器足够聪明,知道myproc就着一个地方用了,甚至还可以节省对myproc的new Proc转换,直接作inline优化 我说的是概念上不应当区分block/proc,不是说解释器实现的时候不可以做特殊化处理。 比如说,1+2,概念上1要变成一个对象然后调用method +(这样保持了everything is object的概念一致性)。但是实现起来解释器完全可以直接作原始类型的加法。并不一定需要因为考虑到原始类型比object效率高就要在语言语义层面区分int和Integer。 至于说&proc是语法糖。我要的不是语法糖,而是取消多余的block/proc在概念上的区别。


uncutstone:
ajoo 写道晕阿。 比如说,1+2,概念上1要变成一个对象然后调用method +(这样保持了everything is object的概念一致性)。但是实现起来解释器完全可以直接作原始类型的加法。并不一定需要因为考虑到原始类型比object效率高就要在语言语义层面区分int和Integer。 至于说&proc是语法糖。我要的不是语法糖,而是取消多余的block/proc在概念上的区别。  Ruby 中 1 本身就是对象。所以不需要转换。 问题的关键是 block 不能是对象。 这其中的原因需要大家思考。我也在思考这个问题。 有一些大致的想法。 假如 block 是对象, 它就要和其它对象一样, 这意味着可以对它调用方法,这也就意味着在 Ruby 中会出现这样的代码: {|x,y| x+y}.call 更糟糕的是:  do |x,y|  x+y end.call 这是不是很怪异呢?


njmzhang:
block效率高是事实,所以block语法和Proc对象都不能取消,剩下的就是block<->Proc的自动转换是否可行的问题...这种转换比1+2的转换难度要大,Yarv里已经实现了对原始类型运算的优化,”+“确实是直接数值运算,不做method call,只要判断这个method没有overload就可以。block到Proc的自动转换不一定这么简单,假如block能自动转换到Proc,那也得等到执行到函数内部也能得知,在调用点还不能做判断,Ruby目前的作法只用有&表示。假如解释器不区分block/proc,单看赋值的话myproc = {|x|...} 这样写比较舒服,解释器可以明白这是要new一个Proc,但是在函数调用时,func(a) {|x|...}就不好说了,倒底是要一个block,还是要a=Proc.new {|x|...}。 而且事实上myproc={|x|...}也有可能是def myproc=(a)end,可以想见解释器确实得"足够"聪明才行。


cfc:
1. def initialize(var1, var2, var3) 2. @var1 = var1 3. @var2 = var2 4. @var3 = var3 5. end我想這個應該可以用  def initialize(*args)  @var1, @var2, @var3 = args[0..2]  end


bencode:
def initialize(var1, var2, var3)
 @var1, @var2, @var3 = var1, var2, var3
end 假如是 Model, 可以使用 Struct A = Struct.new("A", :var1, :var2, :var3)


Underwind:
can i reply this thread?
原文出处:http://www.javaeye.com/topic/25050