In the rare occasions I have to read or write Motoko, I find it tricky, mainly because of having to deploy, making development iterations slow - probably there are better ways around this, as I found out about Haskell (it’s not a language I have knowledge) to write unit-tests, or the Motoko Playground.
What could help is to find how to use the mo:base/Debug to output any custom types, for example?
You can use debug_show(...) which turns any value into Text. Then you can use Debug.print(..) to print the text to console. But you need to deploy your canister locally and call the method in order to run it.
For faster iteration, you can invoke the motoko compiler moc directly. For example, $(dfx cache show)/moc should give you the command.
GitHub - kritzcreek/motoko-matchers is pretty good for writing unit-tests of mainly libraries but also canisters (from dfx), but may have bit-rotted by now.
Some of the motoko-base libraries have their tests written with motoko-matchers.
Yes, PaulLiu, the docs suggest some degree of usefulness for Debug.print + debug_show.
And so in my youthful credulity I expected to enjoy the poetic value of the output of:
public query func get1(): async Nat {
Debug.print("I AM GOING TO RETURN 1 now");
1;
};
by running
dfx canister call bmos get1
How very disappointing was the output of (1 : nat) only!
Not very surprisingly by now, I fail to see how reading
BMOS.mo:1.1-1.34: import error [M0010], package "base" not defined
as a result of
$(dfx cache show)/moc BMOS.mo
can provide for faster iteration.
Would you please point out where my misunderstanding lies?
The debug output only shows up with the replica logs, i.e. in the terminal where you did dfx start or dfx start --background. I know, this is very counter-intuitive. Definitely something to improve.
Yes, you can run it like that after supplying the base library path to moc. For example:
moc --package base $(dfx cache show)/base -r BMOS.mo
The -r option would run the program instead of compiling it. Or you can use -i which will launch into an interactive shell where you can evaluate motoko expressions.
Well, guess I should have realized it myself: WHICH stdout are we talking about, right?
Certainly, I’ll start the replica in the foreground.
But may I make some more use of your helpfulness?
I started adding text to a var _log:Text = “”; and then “looking” at it by means of a query getter.
I know text gets added as expected, but my getter always shows an empty string;
Are variables inside the actor re-initialized / re-evaluated with every invocation?!
I think this isn’t working for you because your function is itself a query so it’s state changes are discarded before returning, including the updates to your Text variable.