On Sun, Nov 28, 2010 at 11:44 AM, Richard Mccormack <
brick / livingwiththehorde.com> wrote:

> def savegame(name, varstosave)
>    savegame = File.new(name + ".tsl", "w")
>    ...
>    savegame.close
> end
>
>
The preferred way to open a file is with the block syntax because it ensures
the file gets closed after the block is evaluated, even if an error gets
raised.

File.open( name + '.tsl' , 'w' ) do |savegame|
  ...
end


>  savegame.puts eval(varstosave[0]).to_s
>
>
For simple things like numbers and strings, this may work (you will probably
have to do some conversions). But for more complex data, like objects, you
will have difficulty because you aren't using any well understood
representation of objects as Strings (others suggested yaml, json,
marshalling).

Use of eval is generally frowned upon because it is rarely necessary and can
introduce security risks. In this case, it is enabling the bad practice of
global variables (I'll explain that a bit further down). Rather than evaling
your global variable strings to get their value, try passing them in to the
function. If you need to keep track of both the name of the variable, and
its value, then try using a hash table.

def savegame(vars)
  vars.each do |name,value|
    puts "savegame has access to #{name} which has a value of #{value}"
  end
end

intellect = 3
strength = 4

savegame 'intellect' => intellect , 'strength' => strength

# output
# >> savegame has access to intellect which has a value of 3
# >> savegame has access to strength which has a value of 4


>
> Where varstoload/varstosave is an array. Problem with the loading is
> that I assumed there  was a way to take the first variable name from the
> array and actually use it as a variable. So, if the array is
> ["$intellect", "$strength"], I thought I would be able somehow to turn
> a[0] into a variable object. It seems that there isn't a way to do this,
> so I was wondering if there was a better way to manage the
> saving/loading.
>

Having a hard time understanding what you are looking for here (it sounds
like you want it to return $intellect, the variable, rather than the object
that the variable is pointing to -- if that is the case, there is no way to
do that)

I will just point out that variables that begin with dollar signs are global
variables in Ruby. Here are the different kinds of variables you can use:

# The colon at the front of the results means that they are Symbols.
# Symbols are basically immutable Strings. In earlier versions of Ruby,
# this would have returned the results as Strings instead of Symbols.

search_pattern = /strength|intelligence/i

$strength = 3
$intelligence = 4
global_variables.grep(search_pattern) # => [:$strength, :$intelligence]

strength = 3
intelligence = 4
local_variables # => [:search_pattern, :strength, :intelligence]

@strength = 3
@intelligence = 4
instance_variables # => [:@strength, :@intelligence]

# this one is a little weird since we are in the main object
@@strenght = 3
@@intelligence = 4
self.class.class_variables # => [:@@strenght, :@@intelligence]

STRENGTH = 3
INTELLIGENCE = 4
self.class.constants.grep(search_pattern) # => [:STRENGTH, :INTELLIGENCE]