# Limiting the scope of a variable

**URL:** <https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366>\
**Category:** Ruby\
**Created:** [May 1, 2008, 9:30am UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366 "2008-05-01T09:30:43Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 9:30am UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/1 "2008-05-01T09:30:43Z")

</div>

Hello,

with a function like that

def let(\*a)  
yield(\*a)  
end

the scope of variables can be limited, e.g. like this:

let {  
x = “foo”  
# … do something with x …  
# here’s the end of scope of x  
}

# …

let {  
x = “bar” # this is another, different x  
# … do something with x …  
}

Is there already a standard means working like this? If it’s a  
standard library function, what’s its name?

Regards  
Thomas

---

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 10:15am UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/2 "2008-05-01T10:15:56Z")

</div>

Why not just use methods?

---

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 11:03am UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/3 "2008-05-01T11:03:58Z")

</div>

On Thu, May 1, 2008 at 8:30 AM, Thomas H.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> def let(\*a)  
> yield(\*a)  
> end
> 
> the scope of variables can be limited, e.g. like this:

The Invocation Construction Kit (Ick) gem includes a “let” function  
(among others). See:

[http://ick.rubyforge.org/](http://ick.rubyforge.org/)

“Ick provides the tools needed to easily build your own execution  
abstractions like the “Maybe” monad or the four canonical block  
evaluators.”

Regards,

Matt.

---

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 11:23am UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/4 "2008-05-01T11:23:21Z")

</div>

Paul McMahon [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote/schrieb [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Why not just use methods?

Inside the block, that is passed to function “let”, many variables  
could be referenced which are defined outside that block. Using  
methods, these variables had to be passed explicitely. Your question  
is a special case of the more general question: Why using blocks at  
all when programming Ruby? Every block could be replaced by a method.

Regards  
Thomas

---

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 5:05pm UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/5 "2008-05-01T17:05:34Z")

</div>

- Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) (13:56) schrieb:

> def let;yield;end

But you can’t pass arguments to the scope. Whatever that might be good  
for.

mfg, simon … l

---

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 2:02pm UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/6 "2008-05-01T14:02:00Z")

</div>

On 01.05.2008 11:13, Thomas H. wrote:

> Paul McMahon [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote/schrieb [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > Why not just use methods?
> 
> Inside the block, that is passed to function “let”, many variables  
> could be referenced which are defined outside that block. Using  
> methods, these variables had to be passed explicitely. Your question  
> is a special case of the more general question: Why using blocks at  
> all when programming Ruby? Every block could be replaced by a method.

I had read Paul’s reply a little differently: this was not about blocks  
vs. methods but about refactoring code. If you find yourself needing to  
separate a lot of scopes inside a method, chances are that your code  
would benefit from refactoring into several methods.

And yes, in that case you do need to pass data explicitly that you need  
inside but this has the advantage of making it clearer which state is  
needed in each section.

Btw, Thomas, this definition serves the same purpose as yours and is  
simpler:

def let;yield;end

You could as well do

1.times {  
x=20

# …

}

🙂

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 5:09pm UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/7 "2008-05-01T17:09:05Z")

</div>

On May 1, 2008, at 1:30 AM, Thomas H. wrote:

> let {  
> Is there already a standard means working like this? If it’s a  
> standard library function, what’s its name?

the simplest way is to use instance\_eval

cfp:~ \> cat a.rb  
instance\_eval {  
x = ‘foo’  
p x  
}

p x rescue :no\_x

instance\_eval {  
x = ‘bar’  
p x  
}

p x rescue :no\_x

cfp:~ \> ruby a.rb  
“foo”  
“bar”

if you prefer you can do

class Object  
alias\_method “scope”, “instance\_eval”  
end

and then

scope{ x = 42; p x }

etc.

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

---

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 6:32pm UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/8 "2008-05-01T18:32:18Z")

</div>

Matt M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote/schrieb  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> The Invocation Construction Kit (Ick) gem includes a “let” function  
> (among others). See:
> 
> [http://ick.rubyforge.org/](http://ick.rubyforge.org/)

Sounds very promising, thanks! Seems that I’m not the first person  
which is missing block structure in Ruby.

Regards  
Thomas

---

<div class="post-metadata">

**Author:** ![samoht](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/ac8455/32.png) [@samoht](https://www.ruby-forum.com/u/samoht)\
**Post date:** [May 1, 2008, 6:30pm UTC](https://www.ruby-forum.com/t/limiting-the-scope-of-a-variable/136366/9 "2008-05-01T18:30:30Z")

</div>

Simon K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote/schrieb  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> But you can’t pass arguments to the scope. Whatever that might be good  
> for.

Yes, that was my intention, especially with regard to Ruby 1.9 and its  
local block parameters - those preceded with “;”. I think the changes  
on those parameters are limited to inside the block, aren’t they? Then  
my Ruby-method “let” has much in common with Scheme’s syntactical form  
“let”, therefore the name. But nevertheless I’d prefer one of Ruby’s  
standard library function, if there’s one which behaves in a similar  
way. Is there one?

Regards  
Thomas
