possible simple marshall error

L

Lex Williams

I recently tried to learn to use Marshal with a simple script , but I
keep getting the following exception : x.rb:6:in `load': marshal data
too short (ArgumentError)

This is the script :

hsh = {:first => [1,2,3],:second => [4,5,6] }

File.open("saved.m","w").puts(Marshal.dump(hsh))

str = (File.open("saved.m").read)
hix = Marshal.load(str) # this appears to be the problem line
hix.each_key do |key|
puts "key : #{key}"
end

could anyone tell me what I'm doing wrong ?
 
A

ara.t.howard

I recently tried to learn to use Marshal with a simple script , but I
keep getting the following exception : x.rb:6:in `load': marshal data
too short (ArgumentError)

This is the script :

hsh = {:first => [1,2,3],:second => [4,5,6] }

File.open("saved.m","w").puts(Marshal.dump(hsh))

str = (File.open("saved.m").read)
hix = Marshal.load(str) # this appears to be the problem line
hix.each_key do |key|
puts "key : #{key}"
end

could anyone tell me what I'm doing wrong ?
--


you are probably on windows and have forgotten to open the file in
binary mode. also, you are re-writing the built-in pstore class, so
you might want to just use that - or at least read over it.

regards.

a @ http://codeforpeople.com/
 
M

Michael Libby

I recently tried to learn to use Marshal with a simple script , but I
keep getting the following exception : x.rb:6:in `load': marshal data
too short (ArgumentError)

This is the script :

hsh = {:first => [1,2,3],:second => [4,5,6] }

File.open("saved.m","w").puts(Marshal.dump(hsh))

This line is actually the problem from what I can tell.

Try instead:

File.open("saved.m", "w"){|f| f.puts(Marshal.dump(hsh)) }
str = (File.open("saved.m").read)

This works, but is more readable as.

str = File.read("saved.m")
hix = Marshal.load(str) # this appears to be the problem line
hix.each_key do |key|
puts "key : #{key}"
end

could anyone tell me what I'm doing wrong ?

Assuming the problem is in the "hard" part of the program. :)

When you have a short snippet like this, running the code line-by-line
in irb is often very helpful, since you can see the return values for
each statement and quickly inspect your variables. At least, that's
what works for me.

-Michael
 
L

Lex Williams

I am using opensuse , could binary files be a issue on linux ?
I tried reading the contents of the file in a iterative fashion , but
the same exception occurs.
 
L

Lex Williams

Michael said:
I recently tried to learn to use Marshal with a simple script , but I
keep getting the following exception : x.rb:6:in `load': marshal data
too short (ArgumentError)

This is the script :

hsh = {:first => [1,2,3],:second => [4,5,6] }

File.open("saved.m","w").puts(Marshal.dump(hsh))

This line is actually the problem from what I can tell.

Try instead:

File.open("saved.m", "w"){|f| f.puts(Marshal.dump(hsh)) }

Thanks Michael , that was the problem indeed . But , what is the
difference between those two language constructs ?
 
M

Michael Libby

I recently tried to learn to use Marshal with a simple script , but I
keep getting the following exception : x.rb:6:in `load': marshal data
too short (ArgumentError)

This is the script :

hsh = {:first => [1,2,3],:second => [4,5,6] }

File.open("saved.m","w").puts(Marshal.dump(hsh))

This line is actually the problem from what I can tell.

Try instead:

File.open("saved.m", "w"){|f| f.puts(Marshal.dump(hsh)) }

And allow me to point out why what you have "should" work (and might
in some cases), but doesn't: buffering.

The way you had it, you open a file, and write to it, but never close
the file before trying to read the file. So what you wrote to the file
is still in the file buffer rather than written to disk. At least this
is how it worked on my system (WindowsXP). I believe this problem
would be the same on Linux.

Using File::eek:pen with a block automatically closes the filehandle at
the end of the block, flushing the buffer and giving the later
File::read something to actually read.

-Michael
 
R

Robert Klemme

I recently tried to learn to use Marshal with a simple script , but I
keep getting the following exception : x.rb:6:in `load': marshal data
too short (ArgumentError)

This is the script :

hsh = {:first => [1,2,3],:second => [4,5,6] }

File.open("saved.m","w").puts(Marshal.dump(hsh))

This line is actually the problem from what I can tell.

To explicitly state it: the issue is caused by not proper closing file
handles.
Try instead:

File.open("saved.m", "w"){|f| f.puts(Marshal.dump(hsh)) }

I'd rather do

File.open("saved.m", "wb"){|f| Marshal.dump(hsh, f) }
This works, but is more readable as.

str = File.read("saved.m")

Again, rather

str = File.open("saved.m","rb") {|f| Marshal.load(f)}
When you have a short snippet like this, running the code line-by-line
in irb is often very helpful, since you can see the return values for
each statement and quickly inspect your variables. At least, that's
what works for me.

Like

irb(main):001:0> File.open("x","wb"){|f| Marshal.dump({1=>2},f)}
=> #<File:x (closed)>
irb(main):002:0> File.open("x","rb"){|f| Marshal.load(f)}
=> {1=>2}
irb(main):003:0>

Kind regards

robert
 
M

Michael Libby

Michael said:
I recently tried to learn to use Marshal with a simple script , but I
keep getting the following exception : x.rb:6:in `load': marshal data
too short (ArgumentError)

This is the script :

hsh = {:first => [1,2,3],:second => [4,5,6] }

File.open("saved.m","w").puts(Marshal.dump(hsh))

This line is actually the problem from what I can tell.

Try instead:

File.open("saved.m", "w"){|f| f.puts(Marshal.dump(hsh)) }

Thanks Michael , that was the problem indeed . But , what is the
difference between those two language constructs ?

See my other post in this thread on buffering. What makes it even
harder to understand the bug in your original code is that the File is
open and the output buffered, so your File::read doesn't have anything
to read. But when the program ends the file handle is closed and the
buffer flushed (data written to the file). So when you go to inspect
the actual file there's your data, looking like it would have been
there all along.

-Michael
 
M

Michael Libby

On 21.08.2008 17:46, Michael Libby wrote:
File.open("saved.m", "w"){|f| f.puts(Marshal.dump(hsh)) }

I'd rather do

File.open("saved.m", "wb"){|f| Marshal.dump(hsh, f) }
[snip]
This works, but is more readable as.

str = File.read("saved.m")

Again, rather

str = File.open("saved.m","rb") {|f| Marshal.load(f)}

Good suggestions.

-Michael
 

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
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top