Feature #4102
Updated by nahi (Hiroshi Nakamura) over 12 years ago
=begin This is a very simple function, it would be implemented as follows: module Kernel private def let() yield end end First of all, do not dismiss this functionality out of hand because of its simplicity. Even though it is just a 'yield', when it is combined with Ruby 1.9's block defaults and new block-variable scoping rules it is actually quite powerful and it behaves exactly like a let* in lisp. Some advantages of this functionality are: (1) Gives you precise control over the scope of your variables. I note that after the publication of "Metaprogramming in Ruby" by Paolo Perrotta the following idiom has started to appear: proc do ..my code.. end.call It is used exactly as the proposed 'let' would be used, but is syntactically much uglier. Yes, i know an alternative is to just make shorter and smaller methods. But is the ability to control and restrict scope ever a bad thing? (2) Testing and teaching about blocks. As the proposed 'let' simply yields to a block it can be used to illustrate block behaviour and block concepts to a new Ruby programmer. It also may be useful to an experienced programmer when trying out new ideas. Here are some example uses of the proposed 'let': Example 1: Carve out a temporary scope, make 'x' local to that scope x = :outer let { |x| x = :inner } #=> :inner x #=> :outer Example 2: Here we use Ruby 1.9's block-defaults to make 'y' block-local and give it a value: let { |y=10| y } #=> 10 Example 3: Make 'x' and 'y' block-local and have 'y' value depend on 'x' (equivalent to let* in lisp) let { |x=10, y=(2*x)| [x, y] } #=> [10, 20] In summary, I think this proposal should succeed for the following reasons: (1) It is an exceptionally simple implementation. (2) More control over scope is never a bad thing. (3) I have seen people re-implementing this functionality themselves using: proc { ..code.. }.call (4) It is very useful for teaching and testing block behaviour. Thanks, John =end