From: Robert Klemme Date: 2003-02-01T02:06:36+09:00 Subject: Re: Local variables & blocks "Yukihiro Matsumoto" schrieb im Newsbeitrag news:1044026420.808845.7614.nullmailer@picachu.netlab.jp... > Hi, > > In message "Re: Local variables & blocks" > on 03/01/31, "Robert Klemme" writes: > > |(i) It's that the control is reversed. Currently the enclosing scope > |defines variables that are visible in the block. This is common behavior > |for most languages and people are used to it. > > But these "most languages" have declaration. So Ruby can (and does) > act differently. Of course. It's just a point that might irritate some people. > |(ii) I don't find it too hard to declare a variable outside the block in > |order to be able to use it inside and after the block. So I personally > |would not gain much. > > I gain much, so it's OK for me. Am I too selfish? ;-) Not if there are enough others that gain, too. :-)) > Since Ruby has no explicit declaration, it is sometimes very hard to > tell whether an identifier is already used as an local variable or > not. This makes code difficult to read. > > |(iii) Binding is deferred to execution time. Currently I don't fully > |oversee all implications of this. Here are some thoughts: It could const > |performance. Runtime errors vs. compile time erros. Errors might be hard to > |track down: think of someone creating a Proc instance, handing that to a > |method that invokes another method etc. until it arrives in the method that > |finally uses it. Maybe the block comes from a different module. Now I > |suddenly get errors because the block creates variables in my method's > |scope, instead of beeing restricted to the creator's scope. > > I'm not sure what you mean. Maybe you're worrying about something I > don't intend. Sorry if I was too terse. Ok, I include another example to check whether I got it right: def blocktest(*args) foo = "hello" p foo args.each do |arg| # local assignment arg = "<#{ arg }>" p arg # creation and assignment to 'bar' in enclosing scope if defined? bar then # append bar.concat( arg.to_s ) else # initialization on first run bar = arg.to_s end foo = "world" end # prints "world" if args was not empty, # "hello" otherwise p foo # prints a string containing all arguments # as strings enclosed in <> if there were any # otherwise raises an error... p bar end Since the initialization seems to be a bit verbose, I must have missed something. At least the test for "defined?" strikes me as unrubyish... > |With the change, will it be possible to do something like this a bit > |artifical example? > | > |class C > | def initialize > | @has_run = false > | end > | > | def createProc > | Proc.new { @has_run = true } > | end > | > | def has_run? > | has_run > | end > |end > | > |c = C.new > |p = c.createProc > | > |c.has_run? > | > |a = [] > |a.each { p.call } > |c.has_run? > | > |a << 1 << 2 > |a.each { p.call } > |c.has_run? > > Nothing will change regarding this script behavior (suppose "has_run" > in "has_run?" method is "@has_run"). Yes, indeed. Sorry for the omission. Kind Regards robert