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
-
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.
The statement "Everything is an Object" becomes invalid, because e.g.
a string object instantiated from a literal behaves differently that a
string object instantiated normally via new() (although they share the
same class, and thus should behave the same).
My understanding is, that this is a know-issue and a trade-off due to
performance issues.
The questions are:
b) Is there any way to track (intercept) the instantiation of objects
(especially those instantiated from literals)
1) without a C-level extension
2) with a C-level extension
The interception can be post instantiation.
Underlying Requirement:
Ability to track instantiation of every object within the system.
.
on 2011-06-09 20:41
on 2011-06-10 00:31
Hi,
In message "Re: CORE - Literal Instantiation breaks Object Model"
on Fri, 10 Jun 2011 03:40:27 +0900, Ilias Lazaridis
<ilias@lazaridis.com> writes:
|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.
You don't have to teach me about Ruby's object model. String objects
for literals are already created in the compile time, which is far
before you redefine the initialize method. The individual string
objects from literals are just copy of the already allocated and
initialized objects. The whole purpose of the initialize method is to
initialize newly created objects, as the name suggests. I don't feel
any need to call the (redefined) initialize method for string
literals, that already initialized at the compile time. Even if you
can use it to track object creation, it's only a side-effect. I am
not going to change the language (or its object model) to fit your
purpose better.
In general, if you want a perfect language that satisfies every random
ideas popping in your mind, you'd better design your own language,
rather than trying to hijacking existing one.
|The questions are:
|
|b) Is there any way to track (intercept) the instantiation of objects
|(especially those instantiated from literals)
| 1) without a C-level extension
| 2) with a C-level extension
If you don't care about performance, you can investigate
ObjectSpace#each_object. Note that JRuby turns off the method by
default for performance reason. If you care about performance, I am
afraid that you have to modify the interpreter itself.
matz.
on 2011-06-10 10:34
On Thursday, June 09, 2011 05:30:43 PM Yukihiro Matsumoto wrote: > default for performance reason. If you care about performance, I am > afraid that you have to modify the interpreter itself. Even this has limitations. A few things that aren't in ObjectSpace: Fixnum (but note, Bignum _is_ there) Symbol TrueClass FalseClass NilClass That's just off the top of my head. But I guess that's the best we can do when entirely guessing at Ilias' actual goal -- as we must do every time he posts. The best we have is: > Ability to track instantiation of every object within the system. If he wants to track instantiation for performance reasons -- for example, to see how many objects he's using at a given moment -- then ObjectSpace might work, just slowly. If there's some reason he wants to know when a Fixnum is "created", then ObjectSpace isn't sufficient, and I imagine a C extension is the least that's required.
on 2011-06-10 10:53
On 09.06.2011 20:40, Ilias Lazaridis wrote: > oo_string = String.new("The OO String") > #=> "OBSERVED: The OO String" test > #=> "The Literal String" test If that really had worked the way you’d 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, it’s 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
on 2011-06-10 16:33
On Thu, Jun 9, 2011 at 11:40 AM, Ilias Lazaridis <ilias@lazaridis.com> wrote: > This is essentially a defect, as the consistency of the Object Model > breaks. > > The statement "Everything is an Object" becomes invalid, because > e.g. a string object instantiated from a literal behaves differently that a > string object instantiated normally via new() (although they share the > same class, and thus should behave the same). The logic in this argument is fundamentally flawed. "Everything is an Object" does not mean "every object of the same class behaves the same". Objects of the same class instantiated with different syntax regularly behave differently. Aside from literal vs. new, you have: #allocate vs. #new generally creation via other methods specific to a particular class (e.g., for Procs objects, proc {} vs. lambda {} vs. Proc.new vs ->() {} vs. method() vs. & to capture the block passed to a method) Others in the thread have explained adequately the practical reasons why you can't have <literal> be interpreted as <some-class>.new(<literal>) where both <literals> are identical [as that would produce infinite recursion], but aside from the practicality you are wrong on the basic theory: different initialization mechanism producing objects which are discernably different in the path of method calls involved in their instantiation and/or their behavior later in their lifecycle is not inconsistent with Ruby's object model, it is rather fundamental to it.
on 2011-06-10 19:55
Yukihiro Matsumoto wrote: > In general, if you want a perfect language that satisfies every random > ideas popping in your mind, you'd better design your own language, > rather than trying to hijacking existing one. In this particular case, that's not even necessary. Ioke and Seph already allow overriding of literals. Just use them. jwm
on 2011-06-10 20:00
On 10 , 01:30, Yukihiro Matsumoto <m...@ruby-lang.org> wrote: > | > |This is essentially a defect, as the consistency of the Object Model > |breaks. > > You don't have to teach me about Ruby's object model. I'm writing here in comp.lang.ruby, addressing the public, not you personally. But: of course I can teach you something about the object model, especially because you have designed it. Because you are - as the language designer and implementer - far to deep in the internals, in order to view the model (and the language in general) strictly from a users view. You miss some basics - that's natural. > String objects > for literals are already created in the compile time, which is far > before you redefine the initialize method. Basics: Interpreted language, OO From my (OO user) point of view, there is no compile-time. And my OO-level code supersedes the core-level code. Because the core- level code is simply there to serve my OO-level code (which has more importance). > The individual string > objects from literals are just copy of the already allocated and > initialized objects. you say: "Individual string objects" Those are *not* String objects, as their related initialize method was not called (remember: my user OO-code supersedes naturally the core- level code) If those would be instances of a class like StringLiterals, it would be different. > The whole purpose of the initialize method is to > initialize newly created objects, as the name suggests. The "initialize" method is the constructor. By definition, an object *must* call the constructor, to become an instance of the class. > I don't feel > any need to call the (redefined) initialize method for string > literals, that already initialized at the compile time. This is not about "feelings" and "needs", but about strictness. If I use a valid language-construct to override the constructor, then the language *must* call the modified constructor in order to be compliant to the OO-model/language. If the language designer "feels" otherwise... then it has to control those feelings. Or he must *clearly* state, that those are *not* objects of class String. > Even if you > can use it to track object creation, it's only a side-effect. I am > not going to change the language (or its object model) to fit your > purpose better. Here I'm asking here the public (including you of course), if there's a workaround available / possible. Neither here, nor on the issue-track I've asked you to "change the language (or its object model)", but to deal with an inconsistency - at least to acknowledge the known issue. Knowing that there is an issue, enables interested people to collaborate in order to solve it. > In general, if you want a perfect language that satisfies every random > ideas popping in your mind, you'd better design your own language, > rather than trying to hijacking existing one. I am sorry to hear you talking like this, although I believe it was simply a bad moment. The few issues that I've filed are for sure not "random popping ideas". Mostly, they are either user needs or usage barriers. "hijacking" implies "stealing" "taking away". As for "my language": I'm not interested to design my own language (at least not now). Designing a processor would fit my interests more - but I've no time for such hobbies (as I could most possibly never beat the "big players"). I simply try to use this language, to report issues which can evolve the language positively, whilst increasing it's consistency and flexibility. You don't even have to understand every use-case. There are users which supersede e.g. your ability in framework-design. Those users need some constructs (implementable only in C-core-level), and those constructs enhance the language in general (none is forced to use them or course). The next user will find those constructs build-in and choose the language possibly exactly for this tiny construct. I am talking here about 5 to 10 issues (estimated). > |The questions are: > | > |b) Is there any way to track (intercept) the instantiation of objects > |(especially those instantiated from literals) > | 1) without a C-level extension > | 2) with a C-level extension > > If you don't care about performance, you can investigate > ObjectSpace#each_object. Note that JRuby turns off the method by > default for performance reason. ObjectSpace#each_object is not the solution (by design). A *possible* solution would be this one: Provide Class#cb_object_instantiated_from_literal(object) http://redmine.ruby-lang.org/issues/4845 > If you care about performance, I am > afraid that you have to modify the interpreter itself. Modifying the interpreter is not an option for me - at least not if the modification is not to be included in core. And here comes the most important issue: If a person with over two decades of experience in hard- system- and firmware-design shows interest to contribute on C-core-level, then you should encourage this instead of suggesting that he is trying to "hijack" the language. You should say "ok, Mr. X can help you to find the relevant sources and constructs", not "go find another language or write your own". Finally I'd like to say: The issue "Literal Instantiation breaks Object Model" is crystal- clear. It should not take anyone more than 15min. to accept it as a "known issue, trade-off for execution speed". That's really nothing special. This is how evolution works: accept the issue (weakness, defect, trade- off, ...), collect relevant information, make it available for interested people, wait till someone claims the issue and hopefully comes up with a solution. - "Ruby 2.0 - Everything First Class Objects" Or can it become ruby 1.9.5? .
on 2011-06-10 20:34
2011/6/10 Ilias Lazaridis <ilias@lazaridis.com>: > > But: of course I can teach you something about the object model, > especially because you have designed it. Because you are - as the > language designer and implementer - far to deep in the internals, in > order to view the model (and the language in general) strictly from a > users view. You miss some basics - that's natural. We've been here before: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/... -- Phillip Gawlowski A method of solution is perfect if we can forsee from the start, and even prove, that following that method we shall attain our aim. -- Leibnitz
on 2011-06-10 20:50
On 10 Ιούν, 11:53, Matthias Wächter <matth...@waechter.wiz.at> wrote: > On 09.06.2011 20:40, Ilias Lazaridis wrote: > > > class String > > alias_method :orig_initialize, :initialize > > def initialize(val) > > orig_initialize "OBSERVED: " + val #change to something like: orig_initialize val puts self.inspect > > end > > def my_method_test > > print self.inspect, " test\n" > > end > > end [...] > If that really had worked the way you’d expect it, you had ended up in an endless loop running out of stack levels soon. The reason for this is that [...] - (elaborations of recursion problems with current showcase) I've understood your elaborations. You should not focus on the showcase code, which could be easily rewritten to not fall into this "trap" at all (e.g. placing a simple "puts object.inspect" in the constructor). Please see the reply to Mr. Matsumoto for more details on the essence of this issue (and the general essence subjecting development). > As you see from the above, it’s not just a trade-off for performance reasons. The performance problem is the central one. Everything else comes after, and should be solvable easily. > > 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. Is "NEWOBJ()" the central function, used system-wide (even from the parser)? .
on 2011-06-11 04:25
2011/6/10 Ilias Lazaridis <ilias@lazaridis.com>: > you say: "Individual string objects" > > Those are *not* String objects, as their related initialize > method was not called Um, yes, they are String objects. Having String.initialize called is not required to have a String object. Even ignoring literals, the usual requirement to get an object of a given class in Ruby is to call the class's allocate method. Calling "Klass.new" is a convenience wrapper which is equivalent to calling Klass.allocate.initialize > > The "initialize" method is the constructor. No its not. "initialize" isn't even *a* constructor. The default/standard constructor is the class method "new", which calls the class method "allocate" to get a new object of the class, and then calls the instance method "initialize" on the new object. > By definition, an object *must* call the constructor, to become > an instance of the class. If one accepts that definition, the only thing you might argue is a "constructor" in Ruby is the class method "allocate", since even ignoring literals, calling the class method "allocate" is the only prerequisite for getting an object of the class (the class method "new" will return an object of the class, but it is by calling "allocate" that it gets that object, not by the subsequent call to "initialize", which, as an instance method of the class, requires that the instance already exist before it can be called.) > >> I don't feel >> any need to call the (redefined) initialize method for string >> literals, that already initialized at the compile time. > > This is not about "feelings" and "needs", but about strictness. Yes, and, strictly, you are wrong. > If I use a valid language-construct to override the constructor, > then the language *must* call the modified constructor in > order to be compliant to the OO-model/language. No definition I've ever seen of the OO model requires that a class have only one constructor, nor does any version of the OO model require that objects specified as literals be equivalent to calling the default constructor with an argument that is some function of the specified literal. I can't actually think of any actual language that fits that definition of the OO model. > > Here I'm asking here the public (including you of course), if > there's a workaround available / possible. No. Its not even *logically* possible, much less practical. > > Neither here, nor on the issue-track I've asked you to "change > the language (or its object model)", but to deal with an > inconsistency - at least to acknowledge the known issue. The only issue here is that you have an incoherent understanding of the OO model (I use incoherent in a strict sense: specifically, that it requires something which is logically inconsistent.) > "Ruby 2.0 - Everything First Class Objects" > > Or can it become ruby 1.9.5? That would be a nice goal. The problem with your criticism is that you are aiming it in the wrong direction: literals are first-class objects and don't need changed -- OTOH, blocks and methods aren't (though its possible in each case to create an object from them, which mitigates but doesn't eliminate the issue.)
on 2011-06-11 10:56
Christopher Dicely already hit the most relevant OO and technical concerns, so I'll just address this: On Friday, June 10, 2011 01:00:26 PM Ilias Lazaridis wrote: > But: of course I can teach you something about the object model, > especially because you have designed it. Because you are - as the > language designer and implementer - far to deep in the internals, in > order to view the model (and the language in general) strictly from a > users view. You miss some basics - that's natural. That's some pretty unbelievable arrogance. Really? Let's examine this: > > String objects > > for literals are already created in the compile time, which is far > > before you redefine the initialize method. > > Basics: Interpreted language, OO > > From my (OO user) point of view, there is no compile-time. Of course there is, even from a "user"s point of view: puts 'Hello, world!' class Foo def bar if false a <> b end end end Execute that, and you find that despite the fact that this code will never run (and thus, will never be "interpreted"), the entire file will be rejected by Ruby at compile time. You'll never see that "Hello, world!" message because of a syntax error buried at compile-time, later. As a user, compile-time is also relevant to why symbols work the way they do, and why they're so useful. Pretending to be an uninformed user doesn't mean you're dealing with something more abstract or "pure", it just means you're less informed. For one thing, as Christopher pointed out, 'initialize' isn't the constructor, and having a separate 'initialize' method is something I've seen (and implemented) in other languages. > Those are *not* String objects, as their related initialize method was > not called (remember: my user OO-code supersedes naturally the core- > level code) While the notion of type is also orthogonal to OO-ness, I don't see that being relevant here. These are in every way String objects. If you define methods on String, those methods apply to String literals. This includes your initialize method: oo_string = String.new("The OO String") li_string = "The Literal String" li_string.send :initialize, li_string # Now the rest of the program works as you expected. Their history is irrelevant. You're talking about what they are now, and they are, in fact, Strings, in every sense that is relevant right now. > If those would be instances of a class like StringLiterals, it would > be different. No, it wouldn't. Then you'd be whining that when you overrode 'initialize' in StringLiterals, your initialize still wasn't called! > > I don't feel > > any need to call the (redefined) initialize method for string > > literals, that already initialized at the compile time. > > This is not about "feelings" and "needs", but about strictness. Matz appears to be saying that he'd rather not call the strings' initialize method twice. Do you really think "strictness", in any context, would be satisfied by calling initialize _twice_? > If I use a valid language-construct to override the constructor, then > the language *must* call the modified constructor in order to be > compliant to the OO-model/language. If the language designer "feels" > otherwise... then it has to control those feelings. > > Or he must *clearly* state, that those are *not* objects of class > String. And as wrong as you've been, this is where you cannot possibly be more wrong. Unless you have somehow become Matz' employer, he owes you nothing, and you are in no place to tell him (or anyone else) what they "must" do. Telling them this is not a recipe for cooperation. And you do seem to care about cooperation. > Neither here, nor on the issue-track I've asked you to "change the > language (or its object model)", Oh, but you have. You just did! In fact, you didn't "ask" him, you told him, you _demanded_ that he change the way the language behaves. > The few issues that I've filed are for sure not "random popping > ideas". Mostly, they are either user needs or usage barriers. Giving us some context would go a long way towards establishing the truth of this. > If a person with over two decades of experience in hard- system- and > firmware-design shows interest to contribute on C-core-level, then you > should encourage this instead of suggesting that he is trying to > "hijack" the language. Except you're not that person. You're some random guy on a discussion group. Even if you have the credentials you claim, and even if they are somehow relevant, we only have what you say here to go on. Your real credentials are your contributions to this discussion. And your contributions have been things like telling the creator of a language that they don't understand their own language. You'd think that would be enough of a clue, without the entire community convinced you're not worth talking to. You have it backwards. If you really do want to contribute, it isn't the responsibility of the core people to encourage you, it's your responsibility to demonstrate to them that it is worth their time to help you. > The issue "Literal Instantiation breaks Object Model" is crystal- > clear. It should not take anyone more than 15min. to accept it as a > "known issue, trade-off for execution speed". That's really nothing > special. Are you surprised that you now have several responses that disagree with you? Why do you think that is? Think about it.
on 2011-06-12 16:41
On 10 , 01:30, Yukihiro Matsumoto <m...@ruby-lang.org> wrote: > | > |This is essentially a defect, as the consistency of the Object Model > |breaks. > [...] > String objects for literals are already created in the compile time, which is far > before you redefine the initialize method. [...] This should not matter. In context of irb this becomes more clear (redefinition of the initialize method happens clearly before it's usage.). #String2.rb class String def initialize(val) self.replace(val) puts object_id end def my_method_test print self.inspect, " test\n" end end # command line $ irb irb(main):001:0> original = String.new("original") => "original" irb(main):002:0> load "String2.rb" => true irb(main):003:0> altered = String.new("altered") 21878604 => "altered" irb(main):004:0> altered.my_method_test => "has method <my_method_test>" irb(main):005:0> literal = "literal" => "literal" irb(main):006:0> literal.my_method_test => "has method <my_method_test>" irb(main):007:0> - The initialize method is an integral part of the class String. From the moment that "String2.rb" is loaded, the initialize method of class String has been validly redefined. (The behaviour of the String class within the "irb session" is altered) The altered initialize method is now an integral part of the class String. The altered String object behaves as expected (responds to "my_method_test, initialized via redefined initialize method). The String(Literal) object responds to "my_method_test", but it is was not initialized with the redefined initialize method. - The "Literal Instantiation" calls the original (core-C-level) String initialize method instead of the redefined one (user-language-level). This *breaks* the object model. .
on 2011-06-16 17:51
On 12 Ιούν, 17:39, Ilias Lazaridis <il...@lazaridis.com> wrote: > > In message "Re: CORE - Literal Instantiation breaks Object Model" > > > #String2.rb > class String > def initialize(val) > self.replace(val) > puts object_id > end > def my_method_test > print self.inspect, " test\n" correction, replace: print self.inspect, " test\n" with: 'has method <my_method_test>'
on 2011-06-18 14:40
Ilias Lazaridis, you try to change Ruby in a fundamental but also
totally random way.
Rather than believe your input has any real value, I suggest you to
start your own language instead and leave Ruby - and the community -
alone.
> The initialize method is an integral part of the class String.
Go read the Pickaxe or try to understand Ruby first before you make
statements like that. An "integral part of class String"? Huh?
You simply show that you know nothing about proper OOP design when you
use buzzwords like "integral part" - no kidding eh? The initialize()
method must be important, hmm?
I advice you to go back to Lisp and abuse the mailing lists there - we
don't need you here.
PS: Ilias ignores statements made selectively. His way to "discuss" only
fits when he wants to look at specific statements and ignore others.
He tries to soak up your energy and time.
Ignoring Ilias entirely is by far the best strategy.
on 2011-06-21 04:40
On 9 , 21:39, Ilias Lazaridis <il...@lazaridis.com> wrote: > oo_string = String.new("The OO String") > #=> "OBSERVED: The OO String" test > This is essentially a defect, as the consistency of the Object Model > The questions are: > Ability to track instantiation of every object within the system. Related Issue: Literal Instantiation breaks Object Model http://redmine.ruby-lang.org/issues/4893 Related Issue (Attempt to workaround) Provide Class#cb_object_instantiated_from_literal(object) http://redmine.ruby-lang.org/issues/4845 .
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.