/ / क्यों रूबी में मार्शल का उपयोग करके एक हैश को डंप करना और लोड करना एक फॉर्मेटर को फेंक देता है? - माणिक्य, मार्शलिंग

रूबी में मार्शल का उपयोग करके हैश को डंपिंग और लोड करना क्यों एक प्रारूप त्रुटि फेंक देता है? - रूबी, marshalling

मैं रूबी से चल रहा हूँ RubyInstaller। यहाँ संस्करण है:

C:UsersSathya>ruby -v
ruby 1.9.2p290 (2011-07-09) [i386-mingw32]

यहाँ सटीक कोड है, जो त्रुटि फेंक रहा है:

hashtime = Hash.new(Time.mktime("1970"))
hashtime[1]  = Time.now
=> 2011-10-04 19:26:53 +0530
print hashtime
{1=>2011-10-04 19:26:53 +0530}=> nil
hashtime[1]  = Time.now
=> 2011-10-04 19:27:20 +0530
print hashtime
{1=>2011-10-04 19:27:20 +0530}=> nil
File.open("timehash","w") do |f|
f.write Marshal.dump(hashtime)
end
=> 56

अब, इसे लोड करने की कोशिश कर रहा है।

Marshal.load (File.read("timehash"))

त्रुटि देता है:

ArgumentError: dump format error for symbol(0x42)
from (irb):10:in `load"
from (irb):10
from C:/Ruby192/bin/irb:12:in `<main>"

यह एक त्रुटि क्यों है? क्या मैं कुछ गलत कर रहा हूँ, या यह एक बग है?

मैं विंडोज 7 अल्टीमेट पर चल रहा हूं, 64-बिट


यहां आपके द्वारा बताए गए संपादित डीबग कोड के परिणाम हैं:

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 20:49:52 +0530
hashdump = Marshal.dump(hashtime)
=> "x04b{x06ix06Iu:tTimerx8FxE4ex80<xADGOx06:voffsetix02XM"
hashtime = Marshal.load (hashdump)
=> {1=>2011-10-04 20:49:52 +0530}
print hashtime
{1=>2011-10-04 20:49:52 +0530}=> nil

परिणाम 2 को संपादित करने के लिए:

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 21:04:24 +0530
hashdump = Marshal.dump(hashtime)
=> "x04b{x06ix06Iu:tTimerx8FxE4ex80x92ox8Cx89x06:voffsetix02XM"
print "hashdump: #{hashdump}"
ÅS?ÇÆoîë?:?offseti?XM=> nile
File.open("timehash","w") do |f|
f.write hashdump
end
=> 36
hashdump2 = File.read("timehash")
=> "x04b{x06ix06Iu:tTimenx8FxE4ex80x92ox8Cx89x06:voffsetix02XM"
print "hashdump2: #{hashdump2}"
hashdump2:{?i?Iu:       Time
ÅS?ÇÆoîë?:?offseti?XM=> nil
hashtime2 = Marshal.load (hashdump2)
ArgumentError: dump format error for symbol(0x8c)
from (irb):73:in `load"
from (irb):73
from C:/Ruby192/bin/irb:12:in `<main>"

कुछ वर्णों में से कुछ नहीं निकला, यहाँ एक स्क्रीनशॉट है:

हैश डंप-मार्शल


अब मैं एक समय प्रारूप अलग त्रुटि हो रही है

hashtime = Hash.new
=> {}
hashtime[1] = Time.now
=> 2011-10-04 21:23:15 +0530
hashdump = Marshal.dump(hashtime)
=> "x04b{x06ix06Iu:tTimerx8FxE4ex80xB9xE1xFBxD4x06:voffsetix02X
M"
print "hashdump: #{hashdump}"
ÅΣ←Ç╣ß√╘♠:♂offseti☻XM=> nile
File.open("timehash","wb") do |f|
f.write hashdump
end
=> 36
hashdump2 = File.read("timehash")
=> "x04b{x06ix06Iu:tTimenx8FxE4ex80xB9xE1xFBxD4x06:voffsetix02X
M"
print "hashdump2: #{hashdump2}"
hashdump2:{♠i♠Iu:       Time
ÅΣ←Ç╣ß√╘♠:♂offseti☻XM=> nil
hashtime2 = Marshal.load (hashdump2)
TypeError: marshaled time format differ
from (irb):10:in `_load"
from (irb):10:in `load"
from (irb):10
from C:/Ruby192/bin/irb:12:in `<main>"

उत्तर:

जवाब के लिए 5 № 1

@Josh और @derp से 2 उत्तरों का संयोजन मेरे लिए काम करता है। यहाँ कोड (फ़ाइल में लिखा गया है):

hashtime = Hash.new(Time.mktime("1970"))
hashtime[1]  = Time.now
File.open("timehash","wb") do |f|
f.write Marshal.dump(hashtime)
end
newhash = Marshal.load (File.binread("timehash"))
p newhash
p newhash.default

निम्नलिखित आउटपुट में परिणाम:

c:appsruby>ruby h.rb
{1=>2011-10-05 08:09:43 +0200}
1970-01-01 00:00:00 +0100

जवाब के लिए 12 № 2

आपको द्विआधारी मोड में फ़ाइल में लिखने की आवश्यकता है b फ़ाइल मोड में:

File.open("timehash","wb") do |f|
f.write Marshal.dump(hashtime)
end

डिस्क को लिखने से पहले स्ट्रिंग्स (हमारे डिबगिंग से) की तुलना करके आप इस मुद्दे को देख सकते हैं:

=> "x04b{x06ix06Iu:tTimerx8FxE4ex80x92ox8Cx89x06:voffsetix02XM"
=> "x04b{x06ix06Iu:tTimenx8FxE4ex80x92ox8Cx89x06:voffsetix02XM"
^^

r (कैरिज रिटर्न) को बदलकर ए किया जा रहा है n (नई पंक्ति)

हालाँकि, ऐसा लगता है कि बाइनरी संशोधक के साथ भी आपका सिस्टम आपकी बात नहीं मान रहा है और बदल रहा है r सेवा मेरे n... तो चलिए डेटा को बेस 64 पर एन्कोडिंग करने का प्रयास करते हैं:

File.open("timehash","w") do |f|
hashtime_marshal = Marshal.dump(hashtime)
f.write [hashtime_marshal].pack("m")
end

hashtime_encoded = File.read("timehash")
hashtime = Marshal.load( hashtime_encoded.unpack("m")[0] )

मुझे बताएं कि क्या वह काम करता है?


पुरानी जानकारी:

डॉन "टी कुछ भी पारित करने के लिए Hash.new:

>> hashtime = Hash.new
=> {}
>> hashtime[1] = Time.now
=> Tue Oct 04 10:57:49 -0400 2011
>> hashtime
=> {1=>Tue Oct 04 10:57:49 -0400 2011}
>> File.open("timehash","w") do |f|
?>   f.write Marshal.dump(hashtime)
>> end
=> 22
>> Marshal.load (File.read("timehash"))
(irb):10: warning: don"t put space before argument parentheses
=> {1=>Tue Oct 04 10:57:49 -0400 2011}

प्रलेखन में कहा गया है कि obj पैरामीटर Hash.new डिफ़ॉल्ट मान है ... यह चाहिए जैसा कि आपके पास काम है ... मैं नहीं जानता कि यह क्यों "t ... लेकिन आपके मामले में नहीं है nil एक स्वीकार्य डिफ़ॉल्ट है, बस यह देखने के लिए जांचें कि क्या मान हैं nil और यदि हां, तो एक का उपयोग करें Time.mktime("1970") इसके बजाय उनके लिए।

संपादित करें: हालांकि, मेरे लिए यह समस्या हल हो गई है, लेकिन मैं ओएस एक्स पर विंडोज नहीं हूं। जब आप निम्नलिखित कोड चलाते हैं तो क्या होता है?

hashtime = Hash.new
hashtime[1] = Time.now
hashdump = Marshal.dump(hashtime)
hashtime = Marshal.load (hashdump)
print hashtime

संपादित करें # 2: ठीक। इसलिए Marshal.dump तथा Marshal.load काम करने लगते हैं। ऐसा लगता है कि यह फ़ाइल I / O के साथ कुछ है ... कृपया निम्नलिखित कोड के परिणाम पोस्ट करें ...

hashtime = Hash.new
hashtime[1] = Time.now
hashdump = Marshal.dump(hashtime)
print "hashdump: #{hashdump}"
File.open("timehash","w") do |f|
f.write hashdump
end
hashdump2 = File.read("timehash")
print "hashdump2: #{hashdump2}"
hashtime2 = Marshal.load (hashdump2)
print hashtime2

उत्तर के लिए 7 № 3

के साथ पढ़ने के बजाय File.read प्रयत्न File.binread या File.open("timehash", "rb")