Feature #4102
closedProposal for 'let'. A new approach using block-defaults in 1.9
Description
=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