(newbie Q) opposite of inspect for strings

  • Thread starter Basile Starynkevitch [news]
  • Start date
B

Basile Starynkevitch [news]

Dear All

I am a novice in Ruby, and I appologize for asking such a basic
questions, but I did not found its answer in the Ruby in a Nutshell
book and after 10 minutes of Googling.

What is is opposite of inspect for strings, ie the function parsing
strings external representation (as strings)?

i.e. I do know that "a\tb".inspect gives the 6 character string
"\"a\\tb\"" but what is the method or function that, given the
argument "\"a\\tb\"" produces the "a\tb" string of 3 characters?

Also how can I easily parse (ie read) from a file such a string like
the output of inspect?

Again, apologies for asking probably a FAQ (which I didn't found in)

Regards.
 
T

Thomas Adam

What is is opposite of inspect for strings, ie the function parsing
strings external representation (as strings)?

i.e. I do know that "a\tb".inspect gives the 6 character string
"\"a\\tb\"" but what is the method or function that, given the
argument "\"a\\tb\"" produces the "a\tb" string of 3 characters?

I'll try this, assuming I unserstand you correctly.
"a\tb"

Of course, calling to_s() on itself perhaps in this instance is silly,
as you know what it is, but I think that does what you're asking?
Also how can I easily parse (ie read) from a file such a string like
the output of inspect?

Can you provide an example of what you mean? Such as sample data?

-- Thomas Adam
 
J

James Edward Gray II

Dear All

I am a novice in Ruby, and I appologize for asking such a basic
questions, but I did not found its answer in the Ruby in a Nutshell
book and after 10 minutes of Googling.

What is is opposite of inspect for strings, ie the function parsing
strings external representation (as strings)?

i.e. I do know that "a\tb".inspect gives the 6 character string
"\"a\\tb\"" but what is the method or function that, given the
argument "\"a\\tb\"" produces the "a\tb" string of 3 characters?

Is this what you mean?

irb(main):001:0> str = "a\tb"
=> "a\tb"
irb(main):002:0> in_file = str.inspect
=> "\"a\\tb\""
irb(main):003:0> rebuilt = eval in_file
=> "a\tb"
Also how can I easily parse (ie read) from a file such a string like
the output of inspect?

Not sure I understand the question here. Do you know how to open a
file and read from it or is that what you want to see?

James Edward Gray II
 
B

Basile Starynkevitch [news]

(citing me, Basile S.)
I'll try this, assuming I understand you correctly.

Sorry for having expressed myself poorly. I mean

a="a\tb"

binds variable a to a 3 character string (a, tab, b)

aa=a.inspect

binds variable aa to a 6 character string (dblquote, a, backslash, t,
b, dblquote)


I'm desperately seeking a function f such that

b = f(aa)

binds variable b to a 3 character string which is equal to the value
of a, or I am seeking a method m such that

c = aa.m

binds variable c to a 3 character string (a, tab, b) equal to the
value of a.


The to_s method is not a valuable substitute for m since aa.to_s is a
6 character string (equal to aa)

Actually I'm just trying to code in a quick and dirty way a ruby
script dumping into a textual form a (rather small) GDBM file, whoses
keys are all alphanumeric (and data are arbitrary binary strings). So
far, I've managed to code the following script which seems to work.

#! /usr/bin/ruby
# $Id: gdbmdump 1 2005-05-18 20:45:15Z basile $
## -*- ruby -*-

require 'gdbm'

srcdbmname=ARGV[0]
destxtname=ARGV[1]

STDERR.printf("start dumping gdbm %s into %s\n", srcdbmname, destxtname)

if (not File.exists?(srcdbmname)) then
STDERR.printf("source dbm %s does not exist\n", srcdbmname);
exit(1)
end

keyarr=Array::new

GDBM.open(srcdbmname, 0400) do |gdbm|
nbk=0
gdbm.each do |key,val|
if /^[a-zA-Z0-9+*._@,!(){}-]*$/ =~ key then
keyarr << key
nbk = nbk + 1
else
STDERR.printf("bad key %s in file %s\n", key.inspect, srcdbmname);
exit(1)
end
end
STDERR.printf("got and sorting %d keys\n", nbk)
keyarr.sort!
if (File.exists?(destxtname)) then
File.rename(destxtname,destxtname+"~")
end
File.open(destxtname, "w") do |out|
keyarr.each do |key|
val=gdbm[key]
out.printf("%s\t%s\n", key, val.inspect)
end
end
end

STDERR.printf("end dumping gdbm %s into %s\n", srcdbmname, destxtname)

##eof $Id: gdbmdump 1 2005-05-18 20:45:15Z basile $

A typical output of the above script is

ab "12"
cd "45"

where the file starts at the column a, and where keys and data are
separated by a tabulation.

My goal was to code the corresponding loading script gdbmload; the
overall motivation for these 2 scripts is to manage under version
control (Subversion) a GDBM file (by dumping it to & reloading it from
a textual format, and by having a "canonical" dump format of it by
sorting the keys; I don"t want to version control the GDBM binary file
-because it is machine dependent- but a dump format of it, obtained
thru this gdbmdump script and the opposite gdbmload script to be
written)

I am really confused and ashamed of asking such basic questions. My
apologies to all, and a big thanks to Thomas Adam for having taken the
time to answer them.

Regards.
 
E

Eric Hodel

On 18 May 2005, at 14:25, Basile Starynkevitch [news] wrote:

[snip the script]
A typical output of the above script is

ab "12"
cd "45"

where the file starts at the column a, and where keys and data are
separated by a tabulation.

My goal was to code the corresponding loading script gdbmload; the
overall motivation for these 2 scripts is to manage under version
control (Subversion) a GDBM file (by dumping it to & reloading it from
a textual format, and by having a "canonical" dump format of it by
sorting the keys; I don"t want to version control the GDBM binary file
-because it is machine dependent- but a dump format of it, obtained
thru this gdbmdump script and the opposite gdbmload script to be
written)

Ah-ha!

You want YAML. It gives you a great plain-text representation that
you can load/dump with ease and works great with revision control.
 
J

Jacob Fugal

Sorry for having expressed myself poorly. I mean
=20
a=3D"a\tb"
=20
binds variable a to a 3 character string (a, tab, b)
=20
aa=3Da.inspect
=20
binds variable aa to a 6 character string (dblquote, a, backslash, t,
b, dblquote)
=20
I'm desperately seeking a function f such that
=20
b =3D f(aa)
=20
binds variable b to a 3 character string which is equal to the value
of a, or I am seeking a method m such that
=20
c =3D aa.m
=20
binds variable c to a 3 character string (a, tab, b) equal to the
value of a.
=20
The to_s method is not a valuable substitute for m since aa.to_s is a
6 character string (equal to aa)

What you probably need is eval:

irb(main):001:0> VERSION
=3D> "1.8.2"
irb(main):002:0> a =3D "a\tb"
=3D> "a\tb"
irb(main):003:0> aa =3D a.inspect
=3D> "\"a\\tb\""
irb(main):004:0> b =3D eval(aa)
=3D> "a\tb"
irb(main):005:0> a =3D=3D b
=3D> true

Of course, you want to be careful when using eval, but it should cut
it for the simple case...

Jacob Fugal
 
B

Basile Starynkevitch [news]

What you probably need is eval:

A big thanks for this suggestion!
irb(main):001:0> VERSION
=> "1.8.2"
irb(main):002:0> a = "a\tb"
=> "a\tb"
irb(main):003:0> aa = a.inspect
=> "\"a\\tb\""
irb(main):004:0> b = eval(aa)
=> "a\tb"
irb(main):005:0> a == b
=> true

Of course, you want to be careful when using eval, but it should cut
it for the simple case...

Is there some specialized version which does not evaluate its
(arbitrary) input, but just unformat a formatted string (and no more,
in particular refuse non-string lexemes such as arbitrary [dangerous]
ruby expressions)?

Regards.
 
J

Jacob Fugal

=20
A big thanks for this suggestion!

You're welcome :)
=20
Of course, you want to be careful when using eval, but it should cut
it for the simple case...
=20
Is there some specialized version which does not evaluate its
(arbitrary) input, but just unformat a formatted string (and no more,
in particular refuse non-string lexemes such as arbitrary [dangerous]
ruby expressions)?

Unfortunately no. A possibility would be to write an encapsulating
method using a regex to verify the input:

def unescapeString( str )
raise TypeError, "Argument must be 'just a string'" unless
str =3D~ /some nasty regex/
eval( str )
end

I don't really want to deal with writing that regex, though, so I'll
leave it as an exercise for the reader. :)

Jacob Fugal
 
P

Paul Brannan

There used to be a library out there somewhere for doing this with
almost any object (using #inspect as a marshaling format). It does not
appear to be listed on the RAA, though. I wish I could remember the
name; perhaps someone else remembers it.

Paul
 
B

Basile Starynkevitch [news]

Actually I'm just trying to code in a quick and dirty way a ruby
script dumping into a textual form a (rather small) GDBM file, whoses
keys are all alphanumeric (and data are arbitrary binary strings). So
far, I've managed to code the following script which seems to work.

Thanks to all who replied. Yes, I was missing the cumfort of LISP READ
ability.

Any by the way, I coded in C the equivalent of what I wanted to code
in Ruby. Yo can download it here
http://starynkevitch.net/Basile/gdbmtext.c and it is a tiny utility
dumping & loading GDBM associative files into and from textual files.
I am quite surprise that Debian don"t seems to have such (or an
equivalent) utility (to dump & restore GDBM files into textual
formats)

Again, sorry for this offtopic post, and for my naive questions on
Ruby. If ruby developpers are reading me, they might consider adding
into some future version of Ruby the opposite function of inspect for
strings only (without going into the risks of eval, just parsing
strings...)

Regards.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top