Re: Problem using precompiled Physics::Measure objects

[email protected] (Elizabeth Mattijsen)
Newsgroups perl.perl6.users
Message-ID <[email protected]>
> On 31 Jul 2024, at 06:10, Kevin Pye <[email protected]> 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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.