From: Robert Klemme Date: 2008-09-03T16:26:15+09:00 Subject: Re: Request for Block local methods, and Proc syntax 2008/9/2 Patrick Li : > Thanks for your input guys. You're welcome! > I want to say that I do really like Ruby. I'm just probing to see if > there's improvements that can still be made, or whether it's as good as > it can be already. I have a different approach: I like the challenge to get things working - without trying to change the language. Actually I believe, most of the time language changes are not worthwhile because of the huge potential to wreck havoc on code - and if the language changes a lot code is affected. You can see that from discussions and change notices for even the comparatively small changes that have been done for 1.9. > Oh, and I do realize the ambiguity of my last example. > > Here's my thoughts on that: > > I think you should ALWAYS be able to retrieve the "context" of an object > given an object reference. How does this help the parser in detecting whether it's a proc / lambda or a Hash? Runtime access to the binding does not help here at all. > In compiled, statically-typed languages such as C++ or Java. > objects can access their "class context" by using: > obj.class Well, yes, but with significant differences to Ruby. C++ has extremely limited capabilities in that area. Did you mean C#? > They cannot access their "block context", by well they don't have to, > because Java blocks aren't first-class objects like they are in Ruby. Actually, you can have a kind of closures in Java as well - although not as elegant as in Ruby. interface Foo { void bar(); } public static void doit(Foo f) { f.bar(); } public static void test() { final int i = 10; doit( new Foo() { void bar() { System.out.println("i is " + i); } } ); > I think, given an object, you should be able to access their > "block"/"scope", because Ruby actually treats them as first-class > objects. There is no general "scope" of an object since you can have multiple references to any object. The notion of "scope of an object" does not make sense in Ruby. Btw, your functionality can be achieved without language changes by applying a small change to my first version: 09:29:38 Temp$ ruby dm2.rb intro An image "test" An image 999 extro 09:30:18 Temp$ cat dm2.rb def html(&block) context = Object.new orig = eval("self", block.binding) orig.instance_variables.each do |var| context.instance_variable_set(var, orig.instance_variable_get(var)) end def context.image(x) puts "An image #{x.inspect}" end context.instance_eval &block end @foo = "test" def bar() 999 end html do puts "intro" image @foo image bar puts "extro" end Cheers robert -- use.inject do |as, often| as.you_can - without end