librasteve / raku-Physics-Measure

do calculations on objects with value, units and error
Artistic License 2.0
11 stars 2 forks source link

"in" identified as "imaginary", not "inches" #28

Closed wayland closed 3 years ago

wayland commented 3 years ago
#!/usr/bin/raku

use     Physics::Unit;
use     Physics::Measure;
use     Physics::UnitPostfix;

my $a;

# Works
$a = Length.new('7.27 in');
say $a;

# Fails
$a = Length.new('7.27in');
say $a;

Here's the output:

Physics::Measure::Length.new(value => 7.27, units => Unit.new( factor => 0.0254, offset => 0, defn => 'ft/12', type => '',
          dims => [1,0,0,0,0,0,0,0], dmix => ("ft"=>1).MixHash, 
          names => ['in','inch','inchs']  );
)
Cannot convert 0+7.27i to Real: imaginary part not zero
  in sub extract at [redacted] (Physics::Measure) line 32
  in method new at [redacted] (Physics::Measure) line 53
  in block <unit> at ./intest line 14

Using the same version as last time (0.0.3)

HTH!

librasteve commented 3 years ago

Hi @wayland - thanks for the feedback. The the .new constructor will parse Strings with the defn-extract regex

/^ ( <number> ) \s* ( <-[±]>* ) $/ [see Measure.rakumod line 102]

In this case, raku thinks the that 7.27i is a (complex) number. I think the best way to handle this corner case is to test for both number == complex && first letter = 'i' then insert space and reparse.

This to be closed in v0.0.4 - due in a few weeks.

wayland commented 3 years ago

Sounds good! In the meantime, I'm splitting it apart and putting a space in manually.

librasteve commented 3 years ago

Here it is golfed. Turns out that defined assertion also gets Complex which we don't want.

my regex number is export {
    \S+                     #grab chars
    <?{ +"$/" ~~ Real }>    #assersion coerces via '+' to Numeric (Real && Complex)
    ##<?{ defined +"$/" }>    #assert coerces via '+' to Real
}

#my $s = '7m';
#my $s = '7 m'; 
my $s = '7in';
#my $s = '7 in';

$s ~~ /^ ( <number> ) \s* ( <-[±]>* ) $/;  

my $v = +"$0".Real if $0.defined;
my $u =  "$1".Str  if $1.defined;

say "extracting «$s»: v is «$v», u is «$u»";
librasteve commented 3 years ago

Final version a bit cleaner...

my regex number is export {
    \S+                     #grab chars
    <?{ +"$/" ~~ Real }>    #assert coerces via '+' to Numeric (Real || Complex)
}

and

$s ~~ /^ ( <number> ) \s* ( <-[±]>* ) $/;  
my $v = +$0;
my $u = ~$1;
librasteve commented 3 years ago

Hi @wayland - I have completed this as a HotFix to the Master branch here at GitHub. You can get right away with:

zef uninstall Physics::Measure
zef install --verbose https://github.com/p6steve/raku-Physics-Measure.git

or similar

wayland commented 3 years ago

Cool, thanks!