[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

possible simple marshall error

Lex Williams

8/21/2008 3:34:00 PM

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

9 Answers

ara.t.howard

8/21/2008 3:42:00 PM

0


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


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://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama




Michael Libby

8/21/2008 3:47:00 PM

0

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

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

Lex Williams

8/21/2008 3:49:00 PM

0

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

Lex Williams

8/21/2008 3:53:00 PM

0

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

Michael Libby

8/21/2008 3:54:00 PM

0

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

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

Robert Klemme

8/21/2008 3:56:00 PM

0

On 21.08.2008 17:46, 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.

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

Michael Libby

8/21/2008 3:59:00 PM

0

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 ?

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

Lex Williams

8/21/2008 4:06:00 PM

0

thanks !

it makes sense :)
--
Posted via http://www.ruby-....

Michael Libby

8/21/2008 4:36:00 PM

0

On Thu, Aug 21, 2008 at 10:56 AM, Robert Klemme
<shortcutter@googlemail.com> wrote:
> 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]

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