From: Josh Cheek Date: 2010-11-29T14:52:48+09:00 Subject: Re: Loading variables from a file [Noob Question] --00163630e86977900b04962aae54 Content-Type: text/plain; charset=ISO-8859-1 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] --00163630e86977900b04962aae54--