Re: Object Identification Cold War and the return of autobox.pm (wasRe: UNIVERSAL::ref might make ref( $mocked_obj ) sane)
On 3/2/07, Adam Kennedy [EMAIL PROTECTED] wrote: 99.999% of the time you do not want to really know how something is implemented, you want to remain ignorant. I concur, which is what really pisses me off them IO::String-new(\$string)-isa('IO::Handle') returns false, because the author believes in duck typing over actually having isa describe the interfaces. This comment lead to do some thinking about perls typing and OO structure and why people seem to have a lot of trouble agreeing on things like this. A type in a language like C is a specification of data representation in memory. In an OO language like C++ this gets extended to be a data representation in memory plus a set of methods that represents an interface. But... In Perl the memory organization is orthagonal to the interface. So we have immutable types like SV's, AV's,HV's, CV's, FORMATS, IO, etc. And then through blessing we can associate the same set of methods to any or all of those types. So when you try to fit the Perl model into the C++ model something has to give. The only way to properly map the perl level concepts to C++ is to say that a C++ type is a perl type+a perl class. But because of the history of ref(), and isa() and the way 'type' is misused in the perl literature the distinction is blurred. Some people want to say are you something I can deref as a particular type AND has an interface I know how to use and some people JUST want to say are you something that has an interface I know how to use. Both questions are reasonable and mutually exclusive. One routine cant do both. So for instance to me it seems to reasonable for IO::String to say, no I am not a IO::Handle. Its data representation doesnt use a IO object so its not an IO::Handle, even if it does provide the same method interface. isa() is to some a method that asks the first question, but to others is asks the second question. Now if there was an -implements() utility function as well as the -isa() funcation, then I think IO::Handle would contrive to ensure that IO::String-new(\$string)-implements('IO::Handle') would return true even though IO::String-new(\$string)-isa('IO::Handle') would not. (Im not sure if this is the same as chromatics proposed 'does' function). Anyway, thanks. The comment on duck typing sorta made all this click for me in a way it hasnt before. Cheers, Yves -- perl -Mre=debug -e /just|another|perl|hacker/
Re: Object Identification Cold War and the return of autobox.pm (wasRe: UNIVERSAL::ref might make ref( $mocked_obj ) sane)
On Friday 02 March 2007 00:53, demerphq wrote: *snip good discussion* Now if there was an -implements() utility function as well as the -isa() funcation, then I think IO::Handle would contrive to ensure that IO::String-new(\$string)-implements('IO::Handle') would return true even though IO::String-new(\$string)-isa('IO::Handle') would not. (Im not sure if this is the same as chromatics proposed 'does' function). Yes, that's one of the main motivations for roles. It's in 5.9.4 as UNIVERSAL::DOES(). For the curious who want to do further research, C++ supports structural typing, while Perl's type system is, at least for objects, mostly nominal. The logical approach to a nominal type system appears to lead to allomorphism. For more detail, see: http://www.oreillynet.com/onlamp/blog/2006/08/roles_composable_units_of_obje.html -- c
Re: Object Identification Cold War and the return of autobox.pm (wasRe: UNIVERSAL::ref might make ref( $mocked_obj ) sane)
On 2 Mar 2007, at 00:35, Adam Kennedy wrote: [snip] Well, except you aren't supposed to do that, because if -isa can be overloaded, it can also die or throw an exception. So eval { $obj-isa($class) } falsely ignores errors. [snip] That, of course, depends on whether you want to ignore errors. So far I've never cared about isa throwing exceptions... Adrian
Re: Object Identification Cold War and the return of autobox.pm (wasRe: UNIVERSAL::ref might make ref( $mocked_obj ) sane)
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Moin. On Friday 02 March 2007 08:53:43 demerphq wrote: On 3/2/07, Adam Kennedy [EMAIL PROTECTED] wrote: 99.999% of the time you do not want to really know how something is implemented, you want to remain ignorant. I concur, which is what really pisses me off them IO::String-new(\$string)-isa('IO::Handle') returns false, because the author believes in duck typing over actually having isa describe the interfaces. This comment lead to do some thinking about perls typing and OO structure and why people seem to have a lot of trouble agreeing on things like this. A type in a language like C is a specification of data representation in memory. In an OO language like C++ this gets extended to be a data representation in memory plus a set of methods that represents an interface. But... In Perl the memory organization is orthagonal to the interface. So we have immutable types like SV's, AV's,HV's, CV's, FORMATS, IO, etc. And then through blessing we can associate the same set of methods to any or all of those types. So when you try to fit the Perl model into the C++ model something has to give. The only way to properly map the perl level concepts to C++ is to say that a C++ type is a perl type+a perl class. But because of the history of ref(), and isa() and the way 'type' is misused in the perl literature the distinction is blurred. Some people want to say are you something I can deref as a particular type AND has an interface I know how to use and some people JUST want to say are you something that has an interface I know how to use. Both questions are reasonable and mutually exclusive. One routine cant do both. So for instance to me it seems to reasonable for IO::String to say, no I am not a IO::Handle. Its data representation doesnt use a IO object so its not an IO::Handle, even if it does provide the same method interface. This is the same as me writing a subclass from Foo, then modifying isa() to say no, I am not a Foo. I just re-use 95% of it's code, but I am really not providing the same interface. And so when someone asks Bar-isa('Foo'), the get the right answer. I really don't know why someone (except people writing things like Data::Dumper) would want to peak under the hood of Bar and discern whether it really is (almost) a Foo, or not. isa() is to some a method that asks the first question, but to others is asks the second question. Now if there was an -implements() utility function as well as the -isa() funcation, then I think IO::Handle would contrive to ensure that IO::String-new(\$string)-implements('IO::Handle') would return true even though IO::String-new(\$string)-isa('IO::Handle') would not. (Im not sure if this is the same as chromatics proposed 'does' function). I am not sure why you would have the need for an implements() or does() function. Either the interface is complete (e.g. Bar is a Foo), or it isn't, then Bar isn't a Foo. In the latter case you can only check if certain methods are there, and we already have can() for that. What would does() or implement() do differenly? Tell you that Bar implements a method just like Foo() does? All the best, Tels - -- Signed on Fri Mar 2 11:21:18 2007 with key 0x93B84C15. Get one of my photo posters: http://bloodgate.com/posters PGP key on http://bloodgate.com/tels.asc or per email. We have problems like this all of the time, Kirk said, trying to reassure me. Sometimes its really hard to get things burning. -- http://tinyurl.com/qmg5 -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.2 (GNU/Linux) iQEVAwUBRegJj3cLPEOTuEwVAQLOfQf9HAK5Q0W6myPPcaVqheUV20eQXFb+nw97 9tm407RJAa3FZtW5A8wjHhB7r5NpkFnX0ye6Y8eFC4I2rH2ENyM5EklAnjK0udok FoO64ERgaQNSEiRFbP80naCEM713DibbBCngoyRPML/N0ob1JvPpl0HSm+bj1h4R p/jbkqK+eOghG23ZQt6lBJ5gDA14Mfm2xmyJxrwElExu6qKhrO5oTSutKovfjYax qjHvIVOpZS1WqByj/KYNLu9NYM/n45Sh5CXqKD2wvZvxoJ2xWEsYE4ikLjExlS1z ahGMimto2y6yV9RDiW1Hkb0CkgJlDF0PWmUQEYC9beYKPfKJS7NcKg== =QFWh -END PGP SIGNATURE-
Re: UNIVERSAL::ref might make ref( $mocked_obj ) sane
Michael G Schwern [EMAIL PROTECTED] writes: chromatic wrote: On Thursday 01 March 2007 17:46, Adam Kennedy wrote: Actually, isn't UNIVERSAL::can($x, 'can') still valid? I seem to remember that at one point it was considered the only valid use of UNVERSAL::can directly. That's the only case I can think of too. Hmm, that's a clever way of determining if something is an object. I guess UNIVERSAL::isa($thing, UNIVERSAL) works, too. And UNIVERSAL::can($thing, isa). Not so if your $thing is a non-object sting that happens to be a package name ... [EMAIL PROTECTED]:39:06]~$ perl -le '$thing = main; print for UNIVERSAL::can($thing, isa), UNIVERSAL::isa($thing, UNIVERSAL), eval { $thing-UNIVERSAL::can(can) }' CODE(0x8130278) 1 CODE(0x81302b4) [EMAIL PROTECTED]:39:18]~$ Sorry; I got nothing. Eirik -- All bridge hands are equally likely, but some are more equally likely than others. -- Alan Truscott
Re: UNIVERSAL::ref might make ref( $mocked_obj ) sane
Eirik Berg Hanssen wrote: Michael G Schwern [EMAIL PROTECTED] writes: chromatic wrote: On Thursday 01 March 2007 17:46, Adam Kennedy wrote: Actually, isn't UNIVERSAL::can($x, 'can') still valid? I seem to remember that at one point it was considered the only valid use of UNVERSAL::can directly. That's the only case I can think of too. Hmm, that's a clever way of determining if something is an object. I guess UNIVERSAL::isa($thing, UNIVERSAL) works, too. And UNIVERSAL::can($thing, isa). Not so if your $thing is a non-object sting that happens to be a package name ... Oh yeah. I guess it would have to be C ref $thing UNIVERSAL::isa($thing, UNIVERSAL) . And the first person to point out it doesn't work if $thing is blessed into class 0 gets their face dunked in pancake batter and fried.
Re: Unit vs. use case/functional testing
On 1 Mar 2007, at 16:42, Andrew Gianni wrote: [snip] In this situation, we would still like something in place to ensure that altering the construction of the business rules doesn't cause regression in the application, but we can't (or I'd certainly rather not) simply write unit tests for. It's also not something that really needs to be done by the developers per se, as they can essentially black box the code, testing for output based on input. I'm thinking that it's about time we started formalizing having staff with QA duties who write functional tests against the code. Does this sound sensible? [snip] If you mean having having these tests in addition to the the unit tests yes. These sort of business facing tests are immensely useful. They're not a replacement for unit tests though. I'm less certain about having separate testing staff. I generally find it more effective to have the developers help write the functional tests with whoever is the source of requirements. Doing this before you start implementing a feature is a great way of defining what finished is. When describing tests these days I find Brian Marick's classifications (technology-facing vs business facing tests) more useful descriptive tools than unit/functional/acceptance type descriptions. See http://www.testing.com/cgi-bin/blog/2003/08/21. If so, what tools could you recommend? Should we still just use Test::More but in a more simple manner? Should we write mech tests instead (these are web apps)? Or are there other tools that would be useful? It seems to me that it would be rather laborious to write all of these tests by hand. As chromatic said looking at a FIT framework may well be useful. Test::FIT is, unfortunately, almost completely undocumented. However the code is pretty easy to grok and I've written custom fixtures with it without too much hassle. In general getting the customers to use something that they're comfortable with to input test data is a bonus. For example I've written stuff that allows the client to enter their data in Excel, and then parsed it and thrown it into some Test::Builder based code. You also might want to look at Test::Base, which can be quite handy for this sort of thing. Ingy did a nice presentation of it at some point that I'm sure Google can locate :-) Writing a DSL on top of Test::Builder is another route. Building an application specific subclass of WWW::Mechanize for example. For web apps go play with Selenium. Any insight appreciated. Recommendations on good books on general testing philosophy would also be helpful (I've already got the developer's notebook). For more general testing discussions I'd recommend joining all of: * [EMAIL PROTECTED] * [EMAIL PROTECTED] * [EMAIL PROTECTED] You also might want to look at all or some of: * http://www.testingeducation.org/BBST/ * http://agiletesting.blogspot.com/ * http://www.opensourcetesting.org/ * http://www.testingreflections.com/ * http://www.testdriven.com/ * http://www.testobsessed.com/ * http://nunit.com/blogs/ * http://googletesting.blogspot.com/ * http://www.developertesting.com/ * http://www.kohl.ca/ And possibly a chunk of the stuff under http://del.icio.us/adrianh/ testing :-) Book wise think all of these are pretty good. Lessons Learned in Software Testing: A Context Driven Approach by Cem Kaner, James Bach and Brett Pettichord (more aimed at folk with tester in their job title - but an interesting read) Testing Extreme Programming by Lisa Crispin and Tip House. (obviously slanted towards XP - but that's a good thing :-) Test Driven Development by Kent Beck (everybody should read this) Test Driven Development: A Practical Guide by Dave Astels (some people dislike this book - I quite like it myself, but prefer the Beck) FIT for Developing Software: Framework for Integrated Tests by Robert C. Martin (if you want to know more about FIT testing) If you're dealing with legacy code, or code that's not been developed test first, I'd also thoroughly recommend Working Effectively With Legacy Code by Michael Feathers. Cheers, Adrian
Re: UNIVERSAL::ref might make ref( $mocked_obj ) sane
On 3/2/07, Michael G Schwern [EMAIL PROTECTED] wrote: Eirik Berg Hanssen wrote: Michael G Schwern [EMAIL PROTECTED] writes: chromatic wrote: On Thursday 01 March 2007 17:46, Adam Kennedy wrote: Actually, isn't UNIVERSAL::can($x, 'can') still valid? I seem to remember that at one point it was considered the only valid use of UNVERSAL::can directly. That's the only case I can think of too. Hmm, that's a clever way of determining if something is an object. I guess UNIVERSAL::isa($thing, UNIVERSAL) works, too. And UNIVERSAL::can($thing, isa). Not so if your $thing is a non-object sting that happens to be a package name ... Oh yeah. I guess it would have to be C ref $thing UNIVERSAL::isa($thing, UNIVERSAL) . And the first person to point out it doesn't work if $thing is blessed into class 0 gets their face dunked in pancake batter and fried. Does defined( Scalar::Util::blessed )have cooties? Its the only predicate you've ever had that actually works. Josh
Re: UNIVERSAL::ref might make ref( $mocked_obj ) sane
On Friday 02 March 2007 08:27, Joshua ben Jore wrote: Does defined( Scalar::Util::blessed )have cooties? Its the only predicate you've ever had that actually works. Sometimes I want to detect class methods too. Y'know, at some point it's worth saying Here's how this works. Here are the reliable ways to answer these questions. If someone does something really stupid, their code will break. Let it. I remember patching the documentation for this somewhere. -- c
Re: UNIVERSAL::ref might make ref( $mocked_obj ) sane
Joshua ben Jore wrote: Does defined( Scalar::Util::blessed )have cooties? Its the only predicate you've ever had that actually works. It requires depending on an XS module if you want compatibility pre-5.8.1. I have to worry about stuff like that.
Re: Unit vs. use case/functional testing
Adrian Howard wrote: [snip] Adrian: How about posting this part on http://perl-qa.yi.org/index.php/Main_Page? For more general testing discussions I'd recommend joining all of: * [EMAIL PROTECTED] * [EMAIL PROTECTED] * [EMAIL PROTECTED] You also might want to look at all or some of: * http://www.testingeducation.org/BBST/ * http://agiletesting.blogspot.com/ * http://www.opensourcetesting.org/ * http://www.testingreflections.com/ * http://www.testdriven.com/ * http://www.testobsessed.com/ * http://nunit.com/blogs/ * http://googletesting.blogspot.com/ * http://www.developertesting.com/ * http://www.kohl.ca/ And possibly a chunk of the stuff under http://del.icio.us/adrianh/ testing :-) Book wise think all of these are pretty good. Lessons Learned in Software Testing: A Context Driven Approach by Cem Kaner, James Bach and Brett Pettichord (more aimed at folk with tester in their job title - but an interesting read) Testing Extreme Programming by Lisa Crispin and Tip House. (obviously slanted towards XP - but that's a good thing :-) Test Driven Development by Kent Beck (everybody should read this) Test Driven Development: A Practical Guide by Dave Astels (some people dislike this book - I quite like it myself, but prefer the Beck) FIT for Developing Software: Framework for Integrated Tests by Robert C. Martin (if you want to know more about FIT testing) If you're dealing with legacy code, or code that's not been developed test first, I'd also thoroughly recommend Working Effectively With Legacy Code by Michael Feathers. jimk
Re: UNIVERSAL::ref might make ref( $mocked_obj ) sane
* Michael G Schwern [EMAIL PROTECTED] [2007-03-02 22:35]: Joshua ben Jore wrote: Does defined( Scalar::Util::blessed )have cooties? Its the only predicate you've ever had that actually works. It requires depending on an XS module if you want compatibility pre-5.8.1. Which is the Perlish equivalent of having cooties, I guess. :-) Regards, -- Aristotle Pagaltzis // http://plasmasturm.org/
Re: Custom extensions to META.yml
* David Golden [EMAIL PROTECTED] [2007-02-28T22:39:01] Is there a de facto standard for custom extensions to META.yml? (I didn't see one in the spec.) An example might be fields beginning with a capital letter or X-foo style extensions. E.g. Why not: extensions: CPAN::Reporter: cc_author: 0 (PLEASE let's avoid 'yes' and 'no' as booleans.) If all the extensions are under the module (or, hey, dist) that uses them, then the X-nonsense is avoided. -- rjbs