# Keeping variables across requires?

**URL:** <https://www.ruby-forum.com/t/keeping-variables-across-requires/122223>\
**Category:** Ruby\
**Created:** [December 5, 2007, 6:30pm UTC](https://www.ruby-forum.com/t/keeping-variables-across-requires/122223 "2007-12-05T18:30:15Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [December 5, 2007, 6:30pm UTC](https://www.ruby-forum.com/t/keeping-variables-across-requires/122223/1 "2007-12-05T18:30:15Z")

</div>

I’m making a Befunge interpreter in Ruby - I like to keep my brain  
active. I want to be able to switch between different sets of rules, so  
as well as my base program befunge.rb, I’ve got a file called  
befunge-93.rb that contains the Befunge-93 specification. Like so:

## befunge.rb

## instructions = {} require ‘befunge-93’

## befunge-93.rb

## instructions = {} instructions["+"] = lambda { |a, b| stack.push a+b } instructions["-"] = lambda { |a, b| stack.push b-a } more instructions, snipped.

I do the ‘instructions = {}’ line twice, as it curls up and dies without  
it. But after I’ve included the instructions file, instructions is still  
{}. This hints at the fact that it’s not letting me use the instructions  
variable across the file.

Is there any way to do this? I _could_ do something like:  
File.open(“befunge-93.rb”).each { |instruction| eval(instruction }

But it that’s a valid solution, then I’m Tony Blair.

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [December 5, 2007, 7:59pm UTC](https://www.ruby-forum.com/t/keeping-variables-across-requires/122223/2 "2007-12-05T19:59:09Z")

</div>

On Dec 5, 2007, at 12:30 PM, Peter B. wrote:

> * * *
> 
> without  
> it. But after I’ve included the instructions file, instructions is  
> still  
> {}. This hints at the fact that it’s not letting me use the  
> instructions  
> variable across the file.
> 
> Is there any way to do this?

You really have two variables ‘instructions’, each local to file in  
which it appears. You could use the following trick with a global  
variable:

`
#! /usr/bin/env ruby -w
$instructions = {}
instructions = $instructions
require "xtest"
p instructions
``
instructions = $instructions
instructions["+"] = lambda { |a, b| stack.push a+b }
instructions["-"] = lambda { |a, b| stack.push b-a }
`

Regards, Morton

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [December 5, 2007, 8:13pm UTC](https://www.ruby-forum.com/t/keeping-variables-across-requires/122223/3 "2007-12-05T20:13:46Z")

</div>

Ah, thanks. With Ruby I’m used to not having to do global/local things;  
I didn’t know you could create global ones with $. But now I have  
another problem: The functions I created with lambda {} are now  
returning -1 as their arity.

My new code:

## befunge.rb

## elsif $instructions.include? operator arguments = [] $instructions[operator].arity.times {arguments.push stack.pop} $instructions[operator].call( \*arguments ) else

## befunge-93.rb (just a sample)

## $instructions = {} $instructions["!"] = lambda { |a| stack.push !a} $instructions["`"] = lambda { |a, b| stack.push b\>a ? 1 : 0 } $instructions["\>"] = lambda { xvel = 1; yvel = 0 }

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [December 5, 2007, 8:27pm UTC](https://www.ruby-forum.com/t/keeping-variables-across-requires/122223/4 "2007-12-05T20:27:17Z")

</div>

On Dec 5, 2007 5:13 PM, Peter B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Ah, thanks. With Ruby I’m used to not having to do global/local things;  
> I didn’t know you could create global ones with $. But now I have  
> another problem: The functions I created with lambda {} are now  
> returning -1 as their arity.

AFAIK, that’s a quirk in 1.8. Blocks with no arguments return -1 when  
you  
ask them for their arity. That behavior was redefined in 1.9, and they  
now  
return 0. You can also, currently, pass arguments to those blocks  
without  
any indication that they’ll be ignored.

1.8.6:

irb(main):001:0\> lambda {}.arity  
=\> -1  
irb(main):002:0\> lambda {}.call 1  
=\> nil

1.9.0 (2007-11-28 patchlevel 0):

irb(main):001:0\> lambda {}.arity  
=\> 0  
irb(main):002:0\> lambda {}.call 1  
ArgumentError: wrong number of arguments (1 for 0)

-Vitor.

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [December 5, 2007, 8:47pm UTC](https://www.ruby-forum.com/t/keeping-variables-across-requires/122223/5 "2007-12-05T20:47:49Z")

</div>

Ah, the program was that I didn’t make all the other variables global as  
well. So it ran, but didn’t like it.

Also, if there is any way to include the file without playing around  
with any global malarky, that would be brilliant.

---

<div class="post-metadata">

**Author:** ![bodikp](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/e79b87/32.png) [@bodikp](https://www.ruby-forum.com/u/bodikp)\
**Post date:** [December 5, 2007, 8:53pm UTC](https://www.ruby-forum.com/t/keeping-variables-across-requires/122223/6 "2007-12-05T20:53:06Z")

</div>

On Dec 5, 1:13 pm, Peter B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> arguments = []
> 
> ```
> 
> ## $instructions[“\>”] = lambda { xvel = 1; yvel = 0 }
> 
> –  
> Posted viahttp://www.ruby-forum.com/.

Global state is usually unnecessary. It looks like your code would fit  
naturally into a layout similar to this…

==befunge-93.rb==  
require ‘singleton’

# class Befunge93 include Singleton attr\_accessor :instructions, :stack def initialize @stack = [] @instructions = {} @instructions[“!”] = lambda { | a | @stack.push(!a) } @instructions[“`”] = lambda { | a, b | @stack.push(b\>a ? 1 : 0) } @instructions[“\>”] = lambda { xvel = 1 yvel = 0 } end end

==befunge.rb==  
require ‘befunge-93’

b = Befunge93.instance

#…  
elsif b.instructions.include?(operator)  
arguments = []  
b.instructions[operator].arity.times {  
arguments.push(b.stack.pop)  
}  
b.instructions[operator].call(\*arguments)  
else  
#…

Regards,  
Jordan
