On Mon, Sep 26, 2005 at 02:24:33 +0200, Juerd wrote: > Whenever possible, object should have useful numeric and string > representations. These are generally lossy, but this is not a problem, because > a scalar stays a scalar even after being used in a certain context, and the > object isn't lost. > > When a protocol or data format that already has a string format is represented > as an object, it should of course evaluate to its common string form when used > in string context. Good examples of this can be found in the LWP package. > > Class Num Str > > HTTP::Headers number of headers "Foo: bar{crlf}Bar: baz{crlf}" > HTTP::Status 200 "HTTP/1.1 200 OK" > HTTP::Date universal epochtime "Sun, 06 Nov 1994 08:49:37 GMT" > > HTML::Form number of elements "<form ...>...</form>" > > One must be careful NOT to pick a certain numification or stringification just > because a certain number or string found in the object will be useful. For > code > to be understandable, the numification or stringification must really BE what > the object represents. Again, LWP provides good examples. > > Class Num Str > > HTTP::Request - "GET / HTTP/1.1{crlf}..." > LWP::UserAgent - - > > There's no single obvious meaningful number that represents HTTP::Request, but > a careless designer could try and guess that people would be interested in the > HTTP version number, the number of headers, or the number of bytes in the > body. > It should therefor produce a warning when it's used in numeric context. What > it > returns, is mostly irrelevant but I'd go as far as returning a random number, > just to avoid that people actually do this. (This is no problem. Compare it to > Perl 5's habit of returning the memory address.) There is, however, a good > string representation of an HTTP message. Whether or not this includes the > body > is irrelevant at this point, but if it's know, it probably should. It can > hopefully do so lazily. > > An UserAgent object has no single obvious meaningful number that it > represents, > and it's hard to express a machine as a string too. Still, someone who feels a > need to use every feature that Perl provides, might use the number of requests > and the last requested URL, thinking these would be very popular. In a good > design, it shouldn't be a number or a string at all, because it would lead to > non-obvious code and would require a comment or diving into documentation, and > then an explicit method name serves both ease of programming and readability > much better. > > However, I do think there should be some kind of useful stringification for > ALL > objects, because objects are often printed for debugging purposes. But I > suggest that this be a global method that all objects implicitly inherit from, > and not be defined in the object itself. This helps to make all these > stringified-for-debugging strings look the same (one programmer could for > example perhaps implement a coloured scheme) and to enable us to make using > them fatal. Because every object may have its own attributes or even other > calculations that will be useful for debugging, there must be a way to specify > which ones are used. I think a simple method that returns a string is most > appropriate. > > One example of what this debugging output could be is: > > { LWP::UserAgent(aen3kx) }
This relates to the Debuggable role I proposed a while back... Basically it's an interface that should never be used within actual code, but is used for helping debuggin. The things I consider debugging: Dumping to the screen Using DDD to graph structures Making sure tracing policies have "levels", so that framework code doesn't confuse a user who is trying to trace through their own code. I think that this role should define the dump operator. Perhaps prefix or postfix ?! can work... That seems fairly obvious. For example warn "Done fetching $url, { $ua?! }"; Let's call it the wtf operator. Now to assimilate some more of your ideas: > aen3kx being the id of the object, and {} being simple delimiters to visually > group. Another example, this time with some attributes that a certain method > in > LWP::UserAgent told Perl to use: The debuggable role is allowed to carry an implicit state. The interface that controls the state has to do with further reporting info, or helping the debugger track the progress of an object. For example: $ua.debug_verbosity++; $ua.debug_verbosity--; These increase and decrease the verbosity number (which starts at a default, specific to each class that does Debuggable) to get more info in the ?! output. To control different attributes is entirely specific to the class being debugged. I suppose something along the lines of a debug mask object, that acts like a log filter will be the de-facto standard for any complex dump. > But, as arrays do have a useful way to be represented as a string: > > element1 element2 element3 > > and not { Array(123abc) }. { temp @array.debug_verbosity++; warn @array?!; } Could be useful as: { Array(123abc) lazy=true fully_resolved=true : [ { Scalar(decaf) : element1 }, { Scalar(beef) : element2 }, { Scalar(f00) : element3 }, }, When you are debugging code that does lots of binding and you think you got the binding wrong somewhere > It's all very Perl 5-y, and that's because that is a good way to do it: the > default is useful for debugging, but you can specify different stringification > in case there's an obvious way to stringify. It just gets much less scary to > actually do override stringification. The ref implementation of ?! should probably be just ~ But I think you'll agree with me that stringification and debugging are something completely different, and interpolation does not imply debugging. > Always, string context should be primarily concerned with use, not debugging > or > storage (serialization). Yes! > Whether this use is for presentation to the user, sending over a > wire or storage, the object can't and shouldn't know. Exactly! Thank you for a wonderful post, Juerd -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me does not drink tibetian laxative tea: neeyah!
pgpS0iG4aOT2u.pgp
Description: PGP signature