Forum: Ruby Symbol#inspect bug?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
18ca239ffade6df0b839d26062f173fb?d=identicon&s=25 dbatml (Guest)
on 2005-11-19 00:25
(Received via mailing list)
Hallo,

Symbol#inspect should return a valid symbol literal, right?

But it doesn't for symbols starting with a digit:

irb(main):001:0> p :"9"
:9
=> nil
irb(main):002:0> :9
SyntaxError: compile error
(irb):2: syntax error
         from (irb):2


Dominik
C35ede9febe86d05f8b45c67191de495?d=identicon&s=25 eric.mahurin (Guest)
on 2005-11-19 00:37
(Received via mailing list)
On 11/18/05, Dominik Bathon <dbatml@gmx.de> wrote:
> SyntaxError: compile error
> (irb):2: syntax error
>          from (irb):2
>
>
> Dominik

It also doesn't work for many of the operators:

p(:'=')
:=

p(:=)
SyntaxError: compile error
(irb):14: syntax error
p(:=)


It seems like if the symbol string is not a valid identifier, it
should be quoted by Symbol#inspect.
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 drbrain (Guest)
on 2005-11-19 00:58
(Received via mailing list)
On Nov 18, 2005, at 3:22 PM, Dominik Bathon wrote:

> Symbol#inspect should return a valid symbol literal, right?

Not according to the RDoc:

$ ri Object#inspect
--------------------------------------------------------- Object#inspect
      obj.inspect   => string
------------------------------------------------------------------------
      Returns a string containing a human-readable representation of
      _obj_. If not overridden, uses the +to_s+ method to generate the
      string.

         [ 1, 2, 3..4, 'five' ].inspect   #=> "[1, 2, 3..4, \"five\"]"
         Time.new.inspect                 #=> "Wed Apr 09 08:54:39
CDT 2003"
18ca239ffade6df0b839d26062f173fb?d=identicon&s=25 dbatml (Guest)
on 2005-11-19 01:10
(Received via mailing list)
On Sat, 19 Nov 2005 00:57:28 +0100, Eric Hodel <drbrain@segment7.net>
wrote:

>       Returns a string containing a human-readable representation of
>       _obj_. If not overridden, uses the +to_s+ method to generate the
>       string.
>
>          [ 1, 2, 3..4, 'five' ].inspect   #=> "[1, 2, 3..4, \"five\"]"
>          Time.new.inspect                 #=> "Wed Apr 09 08:54:39 CDT
> 2003"

Yes, but:

$ ri Symbol#inspect
--------------------------------------------------------- Symbol#inspect
      sym.inspect    => string
------------------------------------------------------------------------
      Returns the representation of sym as a symbol literal.

         :fred.inspect   #=> ":fred"
58479f76374a3ba3c69b9804163f39f4?d=identicon&s=25 drbrain (Guest)
on 2005-11-19 02:32
(Received via mailing list)
On Nov 18, 2005, at 4:09 PM, Dominik Bathon wrote:

>>       Returns a string containing a human-readable representation of
>>       _obj_. If not overridden, uses the +to_s+ method to generate
>> the
>>       string.
>
> Yes, but:
>
> $ ri Symbol#inspect
>      Returns the representation of sym as a symbol literal.

I consider Object#inspect to set the intent of all the #inspect
methods, but this may be an oversight.
C35ede9febe86d05f8b45c67191de495?d=identicon&s=25 eric.mahurin (Guest)
on 2005-11-19 04:02
(Received via mailing list)
On 11/18/05, Eric Hodel <drbrain@segment7.net> wrote:
> >> Not according to the RDoc:
> >      Returns the representation of sym as a symbol literal.
>
> I consider Object#inspect to set the intent of all the #inspect
> methods, but this may be an oversight.

For many of the other core classes (and definitely all other immediate
classes), #inspect returns a representation that is eval'able to get
back an equivalent (or the same) object.  When possible, I think that
is what #inspect should do.  I think it is a bug that Symbol#inspect
almost does it, but not quite (quotes some cases but not others).

I found this problem when doing code generation.  For immediate
objects, I embedded the value in the code directly by using #inspect.
I had to put in a hack for Symbol because of the problem discussed.
4b174722d1b1a4bbd9672e1ab50c30a9?d=identicon&s=25 leavengood (Guest)
on 2005-11-19 05:02
(Received via mailing list)
On 11/18/05, Eric Mahurin <eric.mahurin@gmail.com> wrote:
>
> For many of the other core classes (and definitely all other immediate
> classes), #inspect returns a representation that is eval'able to get
> back an equivalent (or the same) object.  When possible, I think that
> is what #inspect should do.  I think it is a bug that Symbol#inspect
> almost does it, but not quite (quotes some cases but not others).

I agree this should be fixed. I wrote something that I think shows all
the problem cases (at least for single characters):

32.upto(126) do |i|
  c = i.chr
  s = ":\"#{c}\""
  if c == "\"" or c == "\\"
    s = ":\"\\#{c}\""
  end
  symbol = eval(s)
  begin
    symbol = eval(symbol.inspect)
  rescue SyntaxError
    puts "Failed to eval inspected form of #{s}"
  end
end

The results:

Failed to eval inspected form of :"!"
Failed to eval inspected form of :"0"
Failed to eval inspected form of :"1"
Failed to eval inspected form of :"2"
Failed to eval inspected form of :"3"
Failed to eval inspected form of :"4"
Failed to eval inspected form of :"5"
Failed to eval inspected form of :"6"
Failed to eval inspected form of :"7"
Failed to eval inspected form of :"8"
Failed to eval inspected form of :"9"
Failed to eval inspected form of :"="
Failed to eval inspected form of :"@"

Ryan
5befe95e6648daec3dd5728cd36602d0?d=identicon&s=25 bob.news (Guest)
on 2005-11-19 11:23
(Received via mailing list)
Eric Mahurin <eric.mahurin@gmail.com> wrote:
>>>>
>>>
> almost does it, but not quite (quotes some cases but not others).
Although I'd agree that Symbol#inspect can be improved and should be
changend (as it's an easy fix) I have a different opinion about the
usage of
inspect in general: even inspect methods of core classes fail to return
something that is proper ruby code.

$ ruby -e 'p Object.new'
#<Object:0x100f6b28>
$ ruby -e 'a=[1];a<<a;p a'
[1, [...]]

> I found this problem when doing code generation.  For immediate
> objects, I embedded the value in the code directly by using #inspect.
> I had to put in a hack for Symbol because of the problem discussed.

IMHO relying on #inspect for code generation is inappropriate.  As the
rdoc
of Object#inspect indicates it's meant to yield a human readable
representation.  If you want to generate code you should use another
mechanism.  For example, you can define a separate method (even if it
calls
#inspect as default implementation).  Or you use YAML / Marshal for
complex
data structures.

Kind regards

    robert
0ec4920185b657a03edf01fff96b4e9b?d=identicon&s=25 matz (Guest)
on 2005-11-19 11:26
(Received via mailing list)
Hi,

In message "Re: Symbol#inspect bug?"
    on Sat, 19 Nov 2005 08:22:20 +0900, "Dominik Bathon" <dbatml@gmx.de>
writes:

|But it doesn't for symbols starting with a digit:
|
|irb(main):001:0> p :"9"
|:9

Which version are you using?

  % ruby -ve 'p :"9"'
  ruby 1.8.4 (2005-10-29) [i486-linux]
  :"9"

So it's reserved to be fixed.

							matz.
C35ede9febe86d05f8b45c67191de495?d=identicon&s=25 eric.mahurin (Guest)
on 2005-11-19 15:43
(Received via mailing list)
On 11/19/05, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
> Which version are you using?
>
>   % ruby -ve 'p :"9"'
>   ruby 1.8.4 (2005-10-29) [i486-linux]
>   :"9"
>
> So it's reserved to be fixed.
>
>                                                         matz.

Thanks matz.  I just downloaded 1.8.4 preview1 and tried this out.  It
looks like only one case isn't fixed yet (:"["):

[eric@localhost ruby-1.8.4]$ ./ruby -v
ruby 1.8.4 (2005-10-29) [i686-linux]

[eric@localhost ruby-1.8.4]$ ./ruby
1.upto(255) do |c0|
    0.upto(255) do |c1|
        str = c0.chr
        str.concat(c1.chr) if c1.nonzero?
        inspect0 = ":#{str.inspect}"
        eval0 = eval(inspect0)
        inspect1 = eval0.inspect
        begin
            eval1 = eval(inspect1)
            eval1==eval0 or puts "#{eval1}!=#{eval0}"
        rescue SyntaxError
            puts "Couldn't eval(#{inspect1} =
eval(#{inspect0}).inspect)"
        end
    end
end

Couldn't eval(:[ = eval(:"[").inspect)


I didn't realize that symbols can't handle empty strings or the null
character until I tried this.
C35ede9febe86d05f8b45c67191de495?d=identicon&s=25 eric.mahurin (Guest)
on 2005-11-19 16:04
(Received via mailing list)
On 11/19/05, Robert Klemme <bob.news@gmx.net> wrote:
>
> $ ruby -e 'p Object.new'
> #<Object:0x100f6b28>
> $ ruby -e 'a=[1];a<<a;p a'
> [1, [...]]

I didn't say all core classes return something evalable for #inspect
(I said many).  Here's the list I see:

FalseClass, TrueClass, NilClass
Fixnum, Bignum
Float
String
Regexp
Symbol - close but no cigar
Class - kind of - it returns a constant for class that can be evaled
Array, Hash, Range - if no recursion and all elements have an evalable
#inspect

> > I found this problem when doing code generation.  For immediate
> > objects, I embedded the value in the code directly by using #inspect.
> > I had to put in a hack for Symbol because of the problem discussed.
>
> IMHO relying on #inspect for code generation is inappropriate.  As the rdoc
> of Object#inspect indicates it's meant to yield a human readable
> representation.  If you want to generate code you should use another
> mechanism.  For example, you can define a separate method (even if it calls
> #inspect as default implementation).  Or you use YAML / Marshal for complex
> data structures.

Notice I said only immediate objects.  This was actually only an
optimization.  For non-immediate objects, I'm putting them in an
instance variable to be accessed by the generated code.  For immediate
objects there was no reason for this as they were immutable and had no
object creation overhead.  Depending on the instance variable usage
overhead vs. object creation overhead, I might do the same for Float
and other immutable, evalable #inspect classes.  Again, this is only
an optimization - handling some classes differently doesn't change the
functionality.
E0ed615bd6632dd23165e045e3c1df09?d=identicon&s=25 florgro (Guest)
on 2005-11-19 16:58
(Received via mailing list)
Eric Mahurin wrote:

> I didn't realize that symbols can't handle empty strings or the null
> character until I tried this.

Well, at least in 1.8.2 they can handle empty strings, but it is
somewhat tricky:

irb(main):001:0> :"#{}"
ArgumentError: interning empty string
         from (irb):1
irb(main):002:0> :"#{""}"
=> :

Symbol#inspect doesn't quite work there, though. :)

Also, there was more cases like :"$10" that don't work in 1.8.2 and I'm
not sure if they have already been fixed for 1.9. I think I listed most
of them in [ruby-core:03573].
D9179cdd918879d0510dfc56411e4772?d=identicon&s=25 discordantus (Guest)
on 2005-11-19 18:50
(Received via mailing list)
On 11/19/05, Eric Mahurin <eric.mahurin@gmail.com> wrote:
> > something that is proper ruby code.
> Fixnum, Bignum
> Float
> String
> Regexp
> Symbol - close but no cigar
> Class - kind of - it returns a constant for class that can be evaled
> Array, Hash, Range - if no recursion and all elements have an evalable #inspect

Float: NaN, Infinity, -Infinity
Class: Class.new #==> #<Class:0x760fe0>
Regexp:
  insert = '#{23}'
    ==>"\#{23}"
  re = /#{insert}/
    ==>/#{23}/
  eval(re.inspect)
    ==>/23/
... where /#{23}/ is a valid regexp which matches 23 hash characters.

Still, I like that for most cases in core classes, #inspect yields an
eval-able value. This makes it a lot nicer for learning Ruby in IRB.

cheers,
Mark
C35ede9febe86d05f8b45c67191de495?d=identicon&s=25 eric.mahurin (Guest)
on 2005-11-19 20:01
(Received via mailing list)
On 11/19/05, Mark Hubbart <discordantus@gmail.com> wrote:

> Float: NaN, Infinity, -Infinity

It's annoying that these aren't constants.

> Class: Class.new #==> #<Class:0x760fe0>

Yeah, I knew Class#inspect was full of holes for it being evalable.

> Regexp:
>   insert = '#{23}'
>     ==>"\#{23}"
>   re = /#{insert}/
>     ==>/#{23}/
>   eval(re.inspect)
>     ==>/23/
> ... where /#{23}/ is a valid regexp which matches 23 hash characters.

I think this is a bug.  These should be equivalent:

irb(main):001:0> /\#{23}/
=> /\#{23}/
irb(main):002:0> /#{'#{23}'}/
=> /#{23}/

Regexp#inspect should always escape '#'.
C1bcb559f87f356698cfad9f6d630235?d=identicon&s=25 hal9000 (Guest)
on 2005-11-19 20:37
(Received via mailing list)
Eric Mahurin wrote:
> Regexp#inspect should always escape '#'.
>

#inspect is for human-readable strings. If they happen
to be evalable, it's a side effect.

Hal
471cefb0444864e2430e9124915b42b9?d=identicon&s=25 nobu.nokada (Guest)
on 2005-11-20 14:40
(Received via mailing list)
Hi,

At Sat, 19 Nov 2005 23:40:16 +0900,
Eric Mahurin wrote in [ruby-talk:166520]:
> Thanks matz.  I just downloaded 1.8.4 preview1 and tried this out.  It
> looks like only one case isn't fixed yet (:"["):

Thank you, fixed it now.
This topic is locked and can not be replied to.