1

I'm trying to integrate text, for a game written in Ruby. To do this, I thought I could save the text itself in a hash. I want the user to choose the language in which to play. (two languages).

I have written the game code, the dictionary and I have separated the call that prints text in another file. In this way I keep the code clean.

I intend to keep the hash, only to contain texts in different languages.

I get the following error when I run the main file(my_game.rb) from the console.

my_game.rb:62:in `enter': undefined local variable or method `eng' for
#<CentralCorridor:0xb7d73d74> (NameError)
           from my_game.rb:35:in `play'
           from my_game.rb:257:in `<main>' code here

I modified the original code, which can be seen as the first paragraph in the comment block.The first line commented out block is equivalent to the text, written in another file.

class CentralCorridor < Scene

def enter()
    puts "#{Language.get(eng, 'sc_enter')}"
=begin
    puts "The Gothons of Planet Percal #25 have invaded your ship and destroyed"
    puts "your entire crew. You are the last survivieng member and your last"
    puts "mission is to get the neutron destruct bomb from the Weapon Armory,"
    puts "put it in the bridge, and blow the ship up after getting into an "
    puts "escape pod."
    puts "\n"
=end

This is the method that seems to be the one that returns the error. I am not sure if I should modify it to accept written arguments from the module. It is implemented within my_game.rb

def play()
    current_scene = @scene_map.opening_scene()
    last_scene = @scene_map.next_scene('finished')

    while current_scene != last_scene
      next_scene_name = current_scene.enter()
      current_scene = @scene_map.next_scene(next_scene_name)
    end

    # be sure to print out the last scene
    current_scene.enter()
  end
end

I have written the code of the hash inside the module and I've referenced in my_game.rb

require "./hash_compos"
require "./language.rb"

class Scene
  def enter()
    puts "This scene is not yet configured. Subclass it and implement enter."
    exit(1)
  end
end
...

The following code is part of the Dictionary which I implemented in the module. The file is called language.rb. And the module has the same name Language

...
      def Language.get(miDict, key, default=nil)
        # Gets the value in a container for the given key, or the default.
        i, k, v = Language.get_slot(miDict, key, default=default)
        return v
      end

      def Language.set(miDict, key, value)
        # Sets the key to the value, replacing any existing value.
        container = Language.get_container(miDict, key)
        i, k, v = Language.get_slot(miDict, key)

        if i >=0
          container[i] = [key, value]
        else
          container.push([key, value])
        end
      end
...

This is the hash. Written in hash_compos.rb. By the functions created in Language.rb I implement a dictionary to try to contain the minimum code.

require './language.rb'

# create a mapping of a scene to text
eng = Language.new()
Language.set(eng, 'The Gothons of Planet Percal #25 have invaded your ship
and destroyed\nyour entire crew. You are the last survivieng member and your
last\nmission is to get the neutron destruct bomb from the Weapon Armory,\nput 
it in the bridge, and blow the ship up after getting into an 
\nescape pod.\n', 'sc_enter')
Language.set(eng, 'txt', 'sc_cc')
...
Hell0
  • 349
  • 1
  • 6
  • 19

3 Answers3

1

The issue comes from the fact that you defined eng as a local variable in hash_compos.rb.

As stated in this answer to a related question

you cannot access local variables defined in required files

A quick fix to this scope issue is to define eng as a constant in hash_compos.rb. To achieve that, just rename the variable to ENG and update all the files referencing it accordingly.

This will make the variable accessible from files requiring hash_compos.rb.

Community
  • 1
  • 1
erasing
  • 526
  • 3
  • 5
  • The problem is that I need a transfusion of brain and no doctor is up. – Hell0 Apr 16 '15 at 06:05
  • The `eng` variable must work within the module. I'm not sure what I say, but I could swear that the variable must be an argument in the constructor that works with the method to print the hash value. I think the problem would be solved if I build a method that is able to print the opposite value passed as an argument. I'll edit the query, and add the entire code from the dictionary. – Hell0 Apr 16 '15 at 07:10
0

Ok, the solution was much simpler than I thought at first. I have chosen to follow the signs that both have suggested, so first things first. Thanks to both of you.

The problem was that I was working with rigid methods that were built to solve a particular problem. I created a new hash, and I've put into it, the text needed. Then I indicated in the "main" .rb file name. I'll write the nomenclature of the dictionary, in case anyone cares. The padding is always optional !!!

#!/path/to/your_bin

Indicating that in the file, is not the best way to print text. So I recommend, encode the file as if we wanted to apply a markdown for a post. a simple:

# Encoding: utf-8

I implemented the hash, declaring a constant variable, as indicated erasing.

VARIABLE = {"key" => "value"}

Then you just have to call the variable by name. Directly. Ruby is responsible for extracting the indicated value when the hash key.

VARIABLE["key"]

Text formatting, fits encoded into the file. Escape sequences are not necessary.

Problem solved.

Hell0
  • 349
  • 1
  • 6
  • 19
-1

The problem is that in the following line you are trying to use eng, but that variable does not exist:

puts "#{Language.get(eng, 'sc_enter')}"

So, based on the code you use elsewhere it looks like you could just assign to eng right before that line:

eng = Language.new
puts "#{Language.get(eng, 'sc_enter')}"
infused
  • 24,000
  • 13
  • 68
  • 78
  • The solution you suggest does not work at all. The error is gone, but the written text in the hash is not printed. Moreover, the variable is already initialized in the module. I do not understand why I should re-initialize ¿? – Hell0 Apr 15 '15 at 18:50