From: "trans (Thomas Sawyer)" Date: 2012-03-18T22:11:57+09:00 Subject: [ruby-core:43448] [ruby-trunk - Feature #4102] Proposal for 'let'. A new approach using block-defaults in 1.9 Issue #4102 has been updated by trans (Thomas Sawyer). It would conflict with RSpec's definition of #let. Other then as a teaching tool for block scope what are the use cases? This seems to have very limited use. I find defining a new method is better way to get clean scope. ---------------------------------------- Feature #4102: Proposal for 'let'. A new approach using block-defaults in 1.9 https://bugs.ruby-lang.org/issues/4102#change-24915 Author: banister (john mair) Status: Assigned Priority: Normal Assignee: matz (Yukihiro Matsumoto) Category: core Target version: =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 -- http://bugs.ruby-lang.org/