This feels like the same conversation we had earlier this week about accessing private methods. :) But maybe there are still a few new points that can be made.
Tom (>>), Moritz (>): >> I need to test some private routines, so is there a way to do that? > > The easiest way to do that is when the class with the private methods > trusts the class that calls them. See for example > http://doc.perl6.org/type/Metamodel::Trusting > http://design.perl6.org/S12.html#Trusts > https://github.com/perl6/roast/blob/master/S12-attributes/trusts.t I would consider all usages of `trusts` a code smell, if nothing else than for the reason that it links your upstream producer (your class) to a downstream producer (your tests), and explicitly talking about something downstream creates an unholy coupling to it, *and* is difficult because you have to predeclare it in some way. > But you should ask yourself if you really, really want this. > > And then you can also do something like: > > my $private_method = $obj.^private_method_table{$methodname}; > $obj.$private_metnod(arguments here) > > but it is rather questionable use of the MOP. I would actually use $obj.^find_private_method, as I showed in that other thread: class C { method !foo { say "OH HAI" } }; my $obj = C.new; my $pm = C.^find_private_method("foo"); $obj.$pm But I would also amend moritz' "rather questionable" by saying that if you do this, even from the comfort of your own tests, you waive certain advantages of good OOP that you then won't get back. That little '^' means "time to cheat" -- if private methods are the walls of a labyrinth preventing you from going wrong, the '^' just took you to "cheat mode" and you can survey the whole labyrinth from above. In my opinion, tests shouldn't have to resort to that. A very small list of things require cheat mode. Tests don't. The reason we deal with all this inside/outside stuff and make some things private, is so that we can reserve the right to evolve them without breaking anything on the outside. Like a <https://en.wikipedia.org/wiki/Ball_bearing>, the insides are supposed to be able to move without creating any friction on the outside. Any kind of coupling with the outside makes that kind of frictionless evolution harder. Going to the MOP to break the privacy couples the tests to the implementation. Beyond that, this simply *shouldn't need to happen* if the tests are written by the same person as the implementation. (A) Either you need to test the method, and then it can happily be made public, or be made an our sub, or a sub outside of the class. (B) Or you keep the method private, but find some other way to test it besides calling it directly. The goal here is to write tests that don't break in the future. In a way, this is what good OOP leads to. Coupling your tests to private methods is a mistake, IMHO. Perl 6 makes this difficult because it's not a good idea. // Carl