On 01/07/2010 11:16 AM, Florian O. wrote:
gives me:
class Date needs to have method `_load’ (TypeError)
The versions of Marshal are identical, but in 1.8, Date has a _dump and
_load method, in 1.9 it does not.
Am I missing something or is this a bug?
Any hints are appreciated.
James is right: the format of Marshal is not guaranteed to be portable
across Ruby versions. Nevertheless some types do work.
Btw, Marshal’s format is binary. Which means two things
-
you should open files in binary mode,
-
printing methods like #puts are not guaranteed to work.
If you observe these rules you can make it work with Time…
robert@fussel:~$ ruby1.8 -e
‘File.open(“x”,“wb”){|i|Marshal.dump(Time.now,i)}’
robert@fussel:~$ ls -l x
-rw-r–r-- 1 robert robert 18 2010-01-07 13:44 x
robert@fussel:~$ ruby19 -e ‘p(File.open(“x”,“rb”){|i|Marshal.load(i)})’
2010-01-07 13:44:40 +0100
robert@fussel:~$
… but apparently neither Date nor DateTime:
robert@fussel:~$ ruby1.8 -r date -e
‘File.open(“x”,“wb”){|i|Marshal.dump(Date.today,i)}’
robert@fussel:~$ ruby19 -r date -e
‘p(File.open(“x”,“rb”){|i|Marshal.load(i)})’
-e:1:in load': class Date needs to have method
_load’ (TypeError)
from -e:1:in block in <main>' from -e:1:in
open’
from -e:1:in `’
robert@fussel:~$
robert@fussel:~$ ruby1.8 -r date -e
‘File.open(“x”,“wb”){|i|Marshal.dump(DateTime.now,i)}’
robert@fussel:~$ ruby19 -r date -e
‘p(File.open(“x”,“rb”){|i|Marshal.load(i)})’
-e:1:in load': class DateTime needs to have method
_load’ (TypeError)
from -e:1:in block in <main>' from -e:1:in
open’
from -e:1:in `’
robert@fussel:~$
It does work for Date and DateTime when only using one version
robert@fussel:~$ ruby19 -r date -e
‘File.open(“x”,“wb”){|i|Marshal.dump(DateTime.now,i)}’
robert@fussel:~$ ruby19 -r date -e
‘p(File.open(“x”,“rb”){|i|Marshal.load(i)})’
#<DateTime: 2010-01-07T13:54:15+01:00
(2356995876177376393/960000000000,1/24,2299161)>
robert@fussel:~$ ruby19 -r date -e
‘File.open(“x”,“wb”){|i|Marshal.dump(Date.today,i)}’
robert@fussel:~$ ruby19 -r date -e
‘p(File.open(“x”,“rb”){|i|Marshal.load(i)})’
#<Date: 2010-01-07 (4910407/2,0,2299161)>
robert@fussel:~$
You have quite a few options:
- use a type that works, e.g. String:
robert@fussel:~$ ruby1.8 -r date -e
‘File.open(“x”,“wb”){|i|Marshal.dump(Date.today.strftime,i)}’
robert@fussel:~$ ruby19 -r date -e
‘p(Date.strptime(File.open(“x”,“rb”){|i|Marshal.load(i)}))’
#<Date: 2010-01-07 (4910407/2,0,2299161)>
robert@fussel:~$
-
create custom Marshalling and demarshalling methods which use types
that work.
-
create your custom date type which encapsulates a Date but uses
customized Marshal serialization.
You can see an example for customized persistence in section “Custom
Persistence” on
http://blog.rubybestpractices.com/posts/rklemme/018-Complete_Class.html
.
- you use another serialization mechanism, like Yaml:
robert@fussel:~$ ruby1.8 -r date -r yaml -e
‘File.open(“x”,“wb”){|i|YAML.dump(Date.today,i)}’
robert@fussel:~$ ruby19 -r date -r yaml -e
‘p(File.open(“x”,“rb”){|i|YAML.load(i)})’
#<Date: 2010-01-07 (4910407/2,0,2299161)>
robert@fussel:~$
- use yet another completely different format.
There are probably more options…
Kind regards
robert