> On 31 Jul 2024, at 06:10, Kevin Pye <kjpr...@pye.id.au> wrote:
> 
> I am trying to build a replacement for the existing Physics::Constants 
> module, but running into problems when loading the pre-compiled version. I 
> want to use code like:
> 
> unit module Physics::Constants;
> 
> use Physics::Unit;
> use Physics::Measure;
> 
> constant \avogadro-constant is export(:DEFAULT, :fundamental, 
> :avogadro-constant) = Measure.new(
>   value => 6.02214076e+23, 
>   error => 0, 
>   units => 'mol⁻¹',
> );
> 
> which compiles and runs quite well. However, when I try to run "mi6 test" 
> which will precompile and then load the code, I get the following output:
> 
> $ mi6 test
> ===SORRY!=== Error while compiling 
> /home/kevin/git/Physics-Constants/t/01-basic.rakutest
> ===SORRY!=== Error while compiling 
> /home/kevin/git/Physics-Constants/lib/Physics/Constants.rakumod 
> (Physics::Constants)
> An exception X::Comp::AdHoc occurred while evaluating a constant:
> Cannot unbox a P6opaque (NQPMu) type object
> at /home/kevin/git/Physics-Constants/lib/Physics/Constants.rakumod 
> (Physics::Constants):6
> Exception details:
>   ===SORRY!=== Error while compiling 
>   Cannot unbox a P6opaque (NQPMu) type object
>   at line 
> 
> at .../Physics-Constants/t/01-basic.rakutest:2
> t/01-basic.rakutest .. Dubious, test returned 1
> No subtests run
> 
> I am guessing that it can't deserialize the serialized Physics::Measure 
> object, but I could be quite wrong.

This appears to be an issue with resolving somewhere deep in the bowels.  In 
RakuAST, the error is slightly more clear:

===SORRY!===
Cannot look up attributes in a RakuAST::Resolver type object. Did you forget a 
'.new'?

I'm pretty sure we won't fix this in the legacy grammar.  I'll be looking at 
fixing this in RakuAST.  Meanwhile, I would also suggest making this an issue 
in the Physics::Measure repo https://github.com/librasteve/raku-Physics-Measure 
so that the author is alerted to this problem, and maybe can figure out what 
tickles it.


> Any ideas on how to make this work?

Put this in lib/Physics/Constants.rakumod:
=====================
use Physics::Unit;
use Physics::Measure;

my $avogadro-constant := Measure.new(
  value => 6.02214076e+23,
  error => 0,
  units => 'mol⁻¹',
);

sub EXPORT {
    Map.new: (:$avogadro-constant)  # must have () to force positional Pair
}
=====================

And then run:

$ raku -Ilib -MConstants -e 'say avogadro-constant'
6.02214076e+23mol⁻¹ ±0

In other words: drop the module statement.  The namespace *from* which you 
export constants, is usually not important.  And use an EXPORT sub 
(https://docs.raku.org/syntax/sub%20EXPORT) to export whatever values that were 
created when the mainline of the module runs.

Disadvantages to this approach:
- you lose the standard capability to selective importing
- the constants are created at module load time, and not serialized


HTH,

Liz

Reply via email to