Determining if a String is marshalled

Hi all,

I was just wondering if there’s a way to determine if a string has been
marshalled without visual inspection. Something along the lines of
"string.marshalled?" or “string.kind_of?(MarshaledString)”. Is there a
regex I could use?

This had me thinking that it would be nice if Marshal.dump returned a
MarshaledString rather than just a String.

The scenario I’m hitting is a client/server setup where the server may
return a marshaled string or a plain string, depending on the plugin it
calls. At the moment I’m resorting to this, which has potential problems:

r = client.gets
begin
rv = Marshal.load®
rescue TypeError
p r
rescue ArgumentError => e
p "R: #{r}"
else
puts rv
end

What do you think?

Regards,

Dan

Hi,

···

In message “Determining if a String is marshalled” on 03/07/16, Daniel Berger djberge@qwest.com writes:

I was just wondering if there’s a way to determine if a string has been
marshalled without visual inspection. Something along the lines of
“string.marshalled?” or “string.kind_of?(MarshaledString)”. Is there a
regex I could use?

Marshal string have its format version embedded at the top 2 bytes (no
magic though). So that

string[0,2] == Marshal.dump(“”)[0,2]

should work for most of the cases.

						matz.

Check for the first two bytes, which are the major/minor version number.
Rather than hard-code it, you could do

marshall_sig = Marshal.dump(“”)[0…1]
marshall_check = /\A#{marshall_sig}/

irb(main):004:0> “abc” =~ marshall_check
=> nil
irb(main):005:0> Marshal.dump(123) =~ marshall_check
=> 0

Of course, the string might actually start with those bytes, but they are
low (“\004\006” on my machine) so unlikely to occur in a normal string.

Regards,

Brian.

···

On Wed, Jul 16, 2003 at 12:45:46AM +0900, Daniel Berger wrote:

I was just wondering if there’s a way to determine if a string has been
marshalled without visual inspection. Something along the lines of
“string.marshalled?” or “string.kind_of?(MarshaledString)”. Is there a
regex I could use?

Brian Candler wrote:

···

On Wed, Jul 16, 2003 at 12:45:46AM +0900, Daniel Berger wrote:

I was just wondering if there’s a way to determine if a string has been
marshalled without visual inspection. Something along the lines of
“string.marshalled?” or “string.kind_of?(MarshaledString)”. Is there a
regex I could use?

Check for the first two bytes, which are the major/minor version number.
Rather than hard-code it, you could do

marshall_sig = Marshal.dump(“”)[0…1]
marshall_check = /\A#{marshall_sig}/

irb(main):004:0> “abc” =~ marshall_check
=> nil
irb(main):005:0> Marshal.dump(123) =~ marshall_check
=> 0

Of course, the string might actually start with those bytes, but they are
low (“\004\006” on my machine) so unlikely to occur in a normal string.

Regards,

Brian.

Thanks Brian and Matz for the info. My only concern might be that a
pack’d string would inadvertantly pass this test. I guess that’s what
begin/rescue is for, though. :slight_smile:

Regards,

Dan

Of course, the string might actually start with those bytes, but they
are
low (“\004\006” on my machine) so unlikely to occur in a normal string.

Regards,

Brian.

Thanks Brian and Matz for the info. My only concern might be that a
pack’d string would inadvertantly pass this test. I guess that’s what
begin/rescue is for, though. :slight_smile:

Hmm, assuming a packed string can have an arbitrary value,
this could easily happen (probability 1/65536).

Here’s a silly idea. When you Marshal a
string, add a singleton to it (that does
nothing). Test for that later.

str.respond_to? :marshalled # it’s a marshalled string

However, that only works for strings in
memory, of course. If you read it in from
a file… who knows?

Hal

···

----- Original Message -----
From: “Daniel Berger” djberge@qwest.com
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Tuesday, July 15, 2003 11:38 AM
Subject: Re: Determining if a String is marshalled


Hal Fulton
hal9000@hypermetrics.com