Possible simple marshall error

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 ?

···

--
Posted via http://www.ruby-forum.com/.

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/

···

On Aug 21, 2008, at 9:34 AM, Lex Williams wrote:

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 ?
--

--
we can deny everything, except that we have the possibility of being better. simply reflect on that.
h.h. the 14th dalai lama

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. :slight_smile:

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

···

On Thu, Aug 21, 2008 at 10:34 AM, Lex Williams <etaern@yahoo.com> wrote:

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.

···

--
Posted via http://www.ruby-forum.com/.

Michael Libby wrote:

···

On Thu, Aug 21, 2008 at 10:34 AM, Lex Williams <etaern@yahoo.com> wrote:

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 ?
--
Posted via http://www.ruby-forum.com/.

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::open 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

···

On Thu, Aug 21, 2008 at 10:50 AM, Michael Libby <michael.c.libby@gmail.com> wrote:

On Thu, Aug 21, 2008 at 10:34 AM, Lex Williams <etaern@yahoo.com> wrote:

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)) }

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) }

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

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

···

On 21.08.2008 17:46, Michael Libby wrote:

On Thu, Aug 21, 2008 at 10:34 AM, Lex Williams <etaern@yahoo.com> wrote:

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

···

On Thu, Aug 21, 2008 at 10:52 AM, Lex Williams <etaern@yahoo.com> wrote:

Michael Libby wrote:

On Thu, Aug 21, 2008 at 10:34 AM, Lex Williams <etaern@yahoo.com> wrote:

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 ?

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]

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

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

···

On Thu, Aug 21, 2008 at 10:56 AM, Robert Klemme <shortcutter@googlemail.com> wrote:

On 21.08.2008 17:46, Michael Libby wrote:

thanks !

it makes sense :slight_smile:

···

--
Posted via http://www.ruby-forum.com/.