On Wed, 2005-05-25 at 09:11, Piers Cawley wrote: > Aaron Sherman <[EMAIL PROTECTED]> writes:
> > There are many gotchas that fall out of that. For example, you might > > have a special role that overrides .print to handle structured data, so > > your code says: > > > > my Foo $obj; > > given $obj { > > when StructuredPrintRole { > > # Someone's already taken care of it, possibly > > # adding a more specialized role, so leave it > > # alone. > > } > > default { > > # Add in a boring default handler > > $obj does StructuredPrintRole > > } > > } > > $obj.print($structured_data); > > > > Woefully, you lose [if] Foo happens to be DECLARED with > > StructuredPrintRole, and it overrode print. But, if it just inherited a > > print(), then it works. In other words, this code will mysteriously fail > > the second someone innocently adds a print method to Foo! > > > > Action at a distance... my head hurts. > > Aaron, you do realise that that's quite obscene code don't you? Why yes, I think that was my point. This is an unfortunate consequence of the proposed way of mixing in functionality. If this is not what mixins are intended for, then I guess I'm way out in the tall grass, as I'm nearly salivating over the potential. > I mean, you're > doing a case statement based on the type of its topic, And there's something wrong with switching on type? ... I'm sure I have no idea what's wrong with that. As long as smart matching does the right thing with inheritance (and S04 indicates that .does is invoked), this is a pretty traditional way to ask a variable if it "does" what you want. You could explicitly call the .can method, but as this example shows, you don't always want to know if the method EXISTS, but if it supports functionality that you need. > and to compound the > evils, you're changing how your topic's print method works *everywhere* simply > to get your 'special' print behaviour. Yes, that is exactly the point. You have something that behaves like a filehandle, and you wish to tell it to handle structured data. You do this by first asking if it supports the appropriate interface (see S12 for how a role becomes an interface), and failing that, adding a default implementation. This probably looks something like: role StructuredPrintRole { has StructuredLayout $.sdlayout; method print($me: [EMAIL PROTECTED]) returns Int { $me.*SUPER::print(map:{ # A12 shorthand for WALK[:super]:: $_ ~~ StructuredData ?? $me.structure($me.sdlayout) :: $me; }, @list); } } So, by default you can .print to our $obj, and if you support some sort of structured data representation, the right thing happens (even though the "normal" stringification of such a value would not be the same). You might use this for, just as an example, protocol representation of an XImage datastructure for the X protocol. The stringification of it probably isn't the image data -- that wouldn't be terribly useful in general -- but for writing to an X socket, you certainly do want the data to be represented correctly, so you'd derive a role from StructuredPrintRole and tell it how to format X protocol data correctly. > If you must do something like this (and > call it print), then write it as a multimethod or something. I think you're thinking in terms of REPLACING functionality. I'm thinking in terms of AUGMENTING functionality. -- Aaron Sherman <[EMAIL PROTECTED]> Senior Systems Engineer and Toolsmith "It's the sound of a satellite saying, 'get me down!'" -Shriekback