LTA error with missing `use Red:api<2>`
The following error only appears with the code spread across multiple files. If one inlines CITestSetManager.rakumod into test.raku it disappears. It's reproducible.
Select $opt = Red::AST::Select.new(of => DB::CITestSet, fields => Array[Red::AST].new(), filter => Red::AST::Value.new(value => Bool::False, column => Red::Column, type => Bool), order => Array[Red::AST].new(), limit => Int, offset => Int, group => Array[Red::AST].new(), table-list => [], comments => Array[Red::AST::Comment].new(Red::AST::Comment.new(msg => "method 'grep' called at: /home/patrick/repos/RakuCIBot/lib/CITestSetManager.rakumod (CITestSetManager) #5")), sub-select => Bool, prefetch => [])
No such method 'indent' for invocant of type 'Int'. Did you mean any
of these: 'index', 'invert'?
in block at /home/patrick/repos/RakuCIBot/../Red/lib/Red/Driver/CommonSQL.pm6 (Red::Driver::CommonSQL) line 432
in method translate at /home/patrick/repos/RakuCIBot/../Red/lib/Red/Driver/CommonSQL.pm6 (Red::Driver::CommonSQL) line 432
in method prepare at /home/patrick/repos/RakuCIBot/../Red/lib/Red/Driver.pm6 (Red::Driver) line 80
in submethod TWEAK at /home/patrick/repos/RakuCIBot/../Red/lib/Red/ResultSeq/Iterator.pm6 (Red::ResultSeq::Iterator) line 14
in method iterator at /home/patrick/repos/RakuCIBot/../Red/lib/Red/ResultSeq.pm6 (Red::ResultSeq) line 89
in method add-test-set at /home/patrick/repos/RakuCIBot/lib/CITestSetManager.rakumod (CITestSetManager) line 5
in block <unit> at test.raku line 12
DB.rakumod:
use Red:api<2>;
unit module DB;
model CITestSet is rw is table<citest_set> {
has UInt $.id is serial;
has Str $.status is column;
}
CITestSetManager.rakumod:
unit class CITestSetManager;
use DB;
method add-test-set() {
my @asdf = DB::CITestSet.^all.grep(*.status ⊂ <NEW SOURCE_ARCHIVE_CREATED WAITING_FOR_TEST_RESULTS>);
}
test.raku
use CITestSetManager;
use DB;
use Red:api<2>;
my $*RED-DEBUG-AST = True;
my $*RED-DEBUG = True;
red-defaults("SQLite");
schema(DB::CITestSet).create;
my CITestSetManager $tsm .= new;
$tsm.add-test-set();
The reason for the misbehavior is, that CITestSetManager.rakumod missed a use Red:api<2>;.
My concrete problem is now solved, but the error is definitely LTA as it gives no indication whatsoever about what's actually wrong. I'll adapt the title accordingly.
The reason for this, as you may have gathered, is that without the use Red you are not getting the additional operator implementations specific to Red so you wind up with the core operators only. This is similar to e.g. #100
Personally I don't think that there is much that can be done to give a better error message as the grep doesn't know what the matcher is going to do up-front.
Also, which I forgot, is that it is only necessary to use Red::Operator rather than the whole of Red in these cases.
If you really don't want to worry about that you could re-export the Red::Operator exports (the operators,) with something like:
use Red::Operator;
multi EXPORT(|c) {
Map(Red::Operators::EXPORT::ALL::,);
}
In your DB module.
I also can't see how to do that... :(
Can't one just add some probing to the meta methods that look whether the operators are available in the calling scope?
The difficulty is it's not the scope of the methods, it's the scope of, e.g., the matcher supplied to grep which could be defined anywhere and possibly not even use the Red versions of the operators.
It may be possible when we do the RakuAST based version of it and get hid of those operators (if that will be possible)
The difficulty is it's not the scope of the methods, it's the scope of, e.g., the matcher supplied to
grepwhich could be defined anywhere and possibly not even use the Red versions of the operators.
But wouldn't that heuristic catch nearly all cases? I'd assume that the matcher is given inline to grep most of the time.
I'd assume that the matcher is given inline to grep most of the time.
I'd say that in a moderately large or complex program the chances are that the opposite would be true. I'm working on some code at the moment that has a 191 character expression, I definitely wouldn't want to be forced to define that inline (and in this case it can't be because additional logic in the code selects a specific matcher depending on context.)
I definitely wouldn't want to be forced to define that inline
But if the check only emits a warning which can be silenced by adding use Red::Operators:ver<2>; to the top of some file, you wouldn't be forced.
I do agree that such a check wouldn't be considered clean in about any sense of the word. But it might be pragmatic and could be removed at any time as it's only a check.
Maybe something like this could help with that.
I'm reading this issue now and I think I misunderstood that the first time. The thing here, I believe, is that it should be an error, but not an error on the driver. It went too long on the chai without an error. Ideally grep should throw the error, but I'm not sure if that would be possible (but I'll try). In that case Red::AST::Select should have not allowed a new object receiving parameters that are not Red::AST. I'll give it a second try.
I tested it today and I think it's even worst currently... it's not giving error, but it's doing "the wrong thing"...

I think the next commit will fix it:

All tests are failing... it will need some more work... :(
https://github.com/FCO/Red/compare/master...die-if-no-operators
The tests are passing (https://github.com/FCO/Red/pull/562) would you people (@patrickbkr, @jonathanstowe) mind to test it and see if you agree with that?
It seems to be fixed now. Thanks!
@FCO I tried it and am very happy with the result! Thank you very much!
(Two small typos in the error message: s/wou/you/ and s/to True/to True./)
:) great! Thanks for the issue and for the typo reports! Typos fixed!