Print empty values to a file?

Q

Qubert

I am in the middle of writing a wrapper to FORTRAN programs using
Ruby. It going great so far. The problem that I need this groups
help to solve follows:

For the purposes of a reference, a log and to allow continuation of
the script, I have created a function that writes inquired values to a
file, as follows:

def savevaribles
fs = File.new("./savedvaribles.rb","w")
# Saved variables from harmprocessing.rb
fs.puts "# Saved variables from harmprocessing.rb"
fs.puts "$year = #{$year}"
fs.puts "$gonl = #{$gonl}"
fs.puts "$tm = #{$tm}"
fs.puts "$timezone = #{$timezone}"
fs.close
end

Which creates a file that I can "load" with all my variables.
# Saved variables from harmprocessing.rb
$gonl = 149.98435
$tm = 135
$timezone = -9

The list is much more extensive than this and many of the values are
not set until later in the analysis. If the value is not set or if it
is "nil" the commands #{$value} is blank, which is fine except,
$value1 =
$value2 = 42
Upon reading the file, the value of $value1 is set to 42 also, which
confuses further analyses.
So I am trying to figure out a cleaver means to check if each value
exists or nil then 'puts "nil"' so there are no more blanks.
I can do this the brute force method, with if/then statements
everywhere, but I was wondering if there is a Ruby way to accomplish
this.

I appreciate your help.
Chris
 
A

Ara.T.Howard

Date: 26 Jan 2004 08:29:19 -0800
From: Qubert <[email protected]>
Newsgroups: comp.lang.ruby
Subject: Print empty values to a file?

I am in the middle of writing a wrapper to FORTRAN programs using
Ruby. It going great so far. The problem that I need this groups
help to solve follows:

For the purposes of a reference, a log and to allow continuation of
the script, I have created a function that writes inquired values to a
file, as follows:

def savevaribles
fs = File.new("./savedvaribles.rb","w")
# Saved variables from harmprocessing.rb
fs.puts "# Saved variables from harmprocessing.rb"
fs.puts "$year = #{$year}"
fs.puts "$gonl = #{$gonl}"
fs.puts "$tm = #{$tm}"
fs.puts "$timezone = #{$timezone}"
fs.close
end

Which creates a file that I can "load" with all my variables.
# Saved variables from harmprocessing.rb
$gonl = 149.98435
$tm = 135
$timezone = -9

The list is much more extensive than this and many of the values are not set
until later in the analysis. If the value is not set or if it is "nil" the
commands #{$value} is blank, which is fine except, $value1 = $value2 = 42
Upon reading the file, the value of $value1 is set to 42 also, which
confuses further analyses. So I am trying to figure out a cleaver means to
check if each value exists or nil then 'puts "nil"' so there are no more
blanks. I can do this the brute force method, with if/then statements
everywhere, but I was wondering if there is a Ruby way to accomplish this.

I appreciate your help.
Chris

you may want to consider methods which do not require global values, and which
handle all the serialization for you:

~ > cat a.rb
require 'yaml'

module SaveVaribles
PATH = 'sv.yaml'
class << self
def load path = PATH
sv = open(path, 'r'){|f| vars = YAML::load(f)}
end
def save sv, path = PATH
open(path,'w'){|f| f.puts(YAML::dump(sv))}
end
end
end

if File.exist?(SaveVaribles::pATH)
sv = SaveVaribles.load

p sv['year']
p sv['gonl']
p sv['tm']
p sv['timezone']
else
sv = Hash.new

sv['year'] = 2003
sv['gonl'] = nil
sv['tm'] = 'foobar'
sv['timezone'] = 0

SaveVaribles.save sv
end

~ > ruby a.rb

~ > cat sv.yaml
---
timezone: 0
tm: foobar
year: 2003
gonl:

~ > ruby a.rb
2003
nil
"foobar"
0



there is always pstore too:

~ > cat b.rb
require 'pstore'

class SaveVariables < PStore
PATH = 'sv.pstore'
def initialize path=PATH; super; end
def [] k; transaction{super}; end
def []= k,v; transaction{super}; end
def size; transaction{roots.size}; end
def empty?; not size > 0; end
end

sv = SaveVariables.new

if sv.empty?
sv['year'] = 2003
sv['gonl'] = nil
sv['tm'] = 'foobar'
sv['timezone'] = 0
end

sv[:time] = Time.now

p sv['year']
p sv['gonl']
p sv['tm']
p sv['timezone']
p sv[:time]

~ > ruby b.rb && sleep 2 && ruby b.rb
2003
nil
"foobar"
0
Mon Jan 26 03:26:55 MST 2004

2003
nil
"foobar"
0
Mon Jan 26 03:26:57 MST 2004


you definitely have options.

-a
--

ATTN: please update your address books with address below!

===============================================================================
| EMAIL :: Ara [dot] T [dot] Howard [at] noaa [dot] gov
| PHONE :: 303.497.6469
| ADDRESS :: E/GC2 325 Broadway, Boulder, CO 80305-3328
| STP :: http://www.ngdc.noaa.gov/stp/
| NGDC :: http://www.ngdc.noaa.gov/
| NESDIS :: http://www.nesdis.noaa.gov/
| NOAA :: http://www.noaa.gov/
| US DOC :: http://www.commerce.gov/
|
| The difference between art and science is that science is what we
| understand well enough to explain to a computer.
| Art is everything else.
| -- Donald Knuth, "Discover"
|
| /bin/sh -c 'for l in ruby perl;do $l -e "print \"\x3a\x2d\x29\x0a\"";done'
===============================================================================
 
R

Robert Klemme

Qubert said:
I am in the middle of writing a wrapper to FORTRAN programs using
Ruby. It going great so far. The problem that I need this groups
help to solve follows:

For the purposes of a reference, a log and to allow continuation of
the script, I have created a function that writes inquired values to a
file, as follows:

def savevaribles
fs = File.new("./savedvaribles.rb","w")
# Saved variables from harmprocessing.rb
fs.puts "# Saved variables from harmprocessing.rb"
fs.puts "$year = #{$year}"
fs.puts "$gonl = #{$gonl}"
fs.puts "$tm = #{$tm}"
fs.puts "$timezone = #{$timezone}"
fs.close
end

A first remark: you should definitely use the block form:

File.open("savedvaribles.rb", "w") do |fs|
fs.puts "# Saved variables from harmprocessing.rb"
# ...
end

This way you ensure the file is closed properly, regardless how you leave
the block.
Which creates a file that I can "load" with all my variables.
# Saved variables from harmprocessing.rb
$gonl = 149.98435
$tm = 135
$timezone = -9

The list is much more extensive than this and many of the values are
not set until later in the analysis. If the value is not set or if it
is "nil" the commands #{$value} is blank, which is fine except,
$value1 =
$value2 = 42
Upon reading the file, the value of $value1 is set to 42 also, which
confuses further analyses.
So I am trying to figure out a cleaver means to check if each value
exists or nil then 'puts "nil"' so there are no more blanks.
I can do this the brute force method, with if/then statements
everywhere, but I was wondering if there is a Ruby way to accomplish
this.

If you don't need to edit those variables by hand you can marshal them. A
convenient way is to use a hash for that

# names must be an array of global variable names like ["$foo", "$bar"]
def save_vars(names)
h = {}
# for globals only
names.each {|name| h[name]=eval name}
save_hash h
end

def save_hash(hash)
File.open("savedvaribles.rb", "wb") do |fs|
Marshal.dump( hash, fs )
end
end

def load_hash
File.open("savedvaribles.rb", "rb") do |fs|
Marshal.load( fs )
end
end

def load_vars
load_hash.each do |name, val|
# note: name contains the name of a global var
# val is referenced directly!
eval "#{name} = val"
end
end

Something along these lines.

robert
 
M

Mike Stok

I am in the middle of writing a wrapper to FORTRAN programs using
Ruby. It going great so far. The problem that I need this groups
help to solve follows:

For the purposes of a reference, a log and to allow continuation of
the script, I have created a function that writes inquired values to a
file, as follows:

def savevaribles
fs = File.new("./savedvaribles.rb","w")
# Saved variables from harmprocessing.rb
fs.puts "# Saved variables from harmprocessing.rb"
fs.puts "$year = #{$year}"
fs.puts "$gonl = #{$gonl}"
fs.puts "$tm = #{$tm}"
fs.puts "$timezone = #{$timezone}"
fs.close
end

Which creates a file that I can "load" with all my variables.

[...]

Have you considered using YAML? YAML (well syck) comes with Ruby 1.8.x
and encodes values; this makes it possible to save nils and strings with
"dangerous content" e.g.

[mike@ratdog mike]$ irb
require 'yaml' => true
data = { 'foo' => "lots\nof\nlines", 'bar' => nil } => {"foo"=>"lots\nof\nlines", "bar"=>nil}
File.open('/tmp/yaml.dat', 'w') do |f| ?> f << data.to_yaml
end
=> # said:
read_data = YAML::load(File.open('/tmp/yaml.dat')) => {"foo"=>"lots\nof\nlines", "bar"=>nil}
read_data['bar'].nil? => true
puts read_data['foo']
lots
of
lines
=> nil

Hope this helps,

Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,141
Messages
2,570,818
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top