[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Keeping variables across requires?

Peter Bunyan

12/5/2007 5:30:00 PM

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.
--
Posted via http://www.ruby-....

5 Answers

Morton Goldberg

12/5/2007 6:59:00 PM

0

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

> 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?


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

<code test.rb>
#! /usr/bin/env ruby -w
$instructions = {}
instructions = $instructions
require "xtest"
p instructions
</code>

<code xtest.rb>
instructions = $instructions
instructions["+"] = lambda { |a, b| stack.push a+b }
instructions["-"] = lambda { |a, b| stack.push b-a }
</code>

Regards, Morton

Peter Bunyan

12/5/2007 7:14:00 PM

0

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 }
---
--
Posted via http://www.ruby-....

Vitor Peres

12/5/2007 7:25:00 PM

0

Note: parts of this message were removed by the gateway to make it a legal Usenet post.

On Dec 5, 2007 5:13 PM, Peter Bunyan <peter.bunyan@gmail.com> 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.

MonkeeSage

12/5/2007 7:46:00 PM

0

On Dec 5, 1:13 pm, Peter Bunyan <peter.bun...@gmail.com> 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.
>
> 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 }
> ---
> --
> Posted viahttp://www.ruby-....

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

Peter Bunyan

12/5/2007 7:48:00 PM

0

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.
--
Posted via http://www.ruby-....