On 09.06.2011 20:40, Ilias Lazaridis wrote:
> class String
>    alias_method :orig_initialize, :initialize
>    def initialize(val)
>      orig_initialize "OBSERVED: " + val
>    end
>    def my_method_test
>      print self.inspect, " test\n"
>    end
> end
>
> oo_string = String.new("The OO String")
> li_string = "The Literal String"
>
> print "Class: ", oo_string.class, " - content: ", oo_string, "\n"
> print "Class: ", li_string.class, " - content: ", li_string, "\n"
> oo_string.my_method_test
> li_string.my_method_test
>
> #OUTPUT
> #=>  Class: String - content: OBSERVED: The OO String
> #=>  Class: String - content: The Literal String
> #=>  "OBSERVED: The OO String" test
> #=>  "The Literal String" test

If that really had worked the way youd expect it, you had ended up in an endless loop running out of stack levels soon. The reason for this is that 
each string literal would have to go through your special initialization routine, including your "The OO String" and, very subtle, the "OBSERVED: " 
string as well. The former would make oo_string into having two times the "OBSERVED: " prefix, once for initializing the string literal, and second 
inside of your explicit String.new() call. But the fact that "OBSERVED: " would require string initialization as well, would lead to an endless loop.

To fix this infinite loop, one would have to initialize a string object prior to hooking initialize() like this:

observed_prefix = "OBSERVED: "

class String
    alias_method :orig_initialize, :initialize
    def initialize(val)
      orig_initialize observed_prefix + val
    end
    []
end

As Matz already pointed out, there are quite some good reasons for letting the parser translate literal constants into objects independent from the 
actual program flow.

> The behaviour of the class String has been altered, whilst using the
> standard mechanisms of the Object Model.
>
> To my huge surprise, although the li_string has been instantiated as
> an object of class String, the new initialize method was not called.
>
> This is essentially a defect, as the consistency of the Object Model
> breaks.

Another question could be why »"OBSERVED: " + val« does not call initialize() on the resulting string right before that result is passed to 
orig_initialize. OTOH, this would lead to another endless loop.

> My understanding is, that this is a know-issue and a trade-off due to
> performance issues.

As you see from the above, its not just a trade-off for performance reasons.

> Underlying Requirement:
> Ability to track instantiation of every object within the system.

This is an interesting idea. I think you have to patch NEWOBJ() in the sources, at least.

 Matthias