Re: Help converting CArray[uint8] to Blob
Hi! > $ed.data.head($ed.data_size) Unfortunately, i get the error "Error X::AdHoc+{X::Await::Died}+{X::React::Died}: Don't know how many elements a C array returned from a library" > > my uint8 @data = $ed.data[0..$ed.data_size-1].Array; > > my Blob $bindata = Blob[uint8].new(@data); > > Afaict that's a total of five HLL element-by-element copies. > > I would expect this to work and be at least as fast and possibly a lot faster: > > my Blob $bindata .= new: $ed.data; Because of the error above, i have to do: my Blob $bindata .= new: $ed.data[^$ed.data_size]; which takes slightly more than 1 sec: Bindata in 1.1679568 Btw, the size of the $ed.data_size is 750K. Regards. David Santiago Ralph Mellor escreveu no dia terça, 16/06/2020 à(s) 23:08: > > > my Data $ed = await $yenc_promise; > > The promise must initialize each element of the CArray[uint]. It looks > pretty quick; I'm guessing it's low-level code doing that. > > > my uint8 @data = $ed.data[0..$ed.data_size-1].Array; > > my Blob $bindata = Blob[uint8].new(@data); > > Afaict that's a total of five HLL element-by-element copies. > > I would expect this to work and be at least as fast and possibly a lot faster: > > my Blob $bindata .= new: $ed.data; > > hth
Re: Help converting CArray[uint8] to Blob
> Unfortunately, i get the error "Error > X::AdHoc+{X::Await::Died}+{X::React::Died}: Don't know how many elements a C array returned from a library" I googled the error message and got a bunch of matches including this: https://stackoverflow.com/questions/51081475/getting-data-out-of-native-pointers This will show the way to maximize the speed because it minimizes the *number* of copy operations (to one) and expense of the copy (by making it native code). hth
Re: Help converting CArray[uint8] to Blob
Super! That what i was looking for, i changed the code to: my Instant $init = DateTime.now.Instant; my Blob $blob = blob-from-carray($ed.data, size=>$ed.data_size); say "bindata = {DateTime.now.Instant-$init}"; Output: Bindata= 0.00060054 So it passed from approx 1.1 to 0.0006 secs. That's quite an improvement! Thank you so much. Best regards, David Santiago Ralph Mellor escreveu no dia quarta, 17/06/2020 à(s) 11:57: > > > Unfortunately, i get the error "Error > > X::AdHoc+{X::Await::Died}+{X::React::Died}: Don't know how many > elements a C array returned from a library" > > I googled the error message and got a bunch of matches including this: > > https://stackoverflow.com/questions/51081475/getting-data-out-of-native-pointers > > This will show the way to maximize the speed because it minimizes > the *number* of copy operations (to one) and expense of the copy > (by making it native code). > > hth
Re: Help converting CArray[uint8] to Blob
Shorter, and much more readable, I'd say: my Blob $blob = blob-from-carray($ed.data, size=>$ed.data_size); say "bindata = { now - INIT now }"; The term "now" is short for "DateTime.now.Instant" The INIT phaser is run when the program is started: it returns the value that was obtained from the code then executed. Phasers for the win! > On 17 Jun 2020, at 19:01, David Santiago wrote: > > Super! > > That what i was looking for, i changed the code to: > > my Instant $init = DateTime.now.Instant; > my Blob $blob = blob-from-carray($ed.data, size=>$ed.data_size); > say "bindata = {DateTime.now.Instant-$init}"; > > > Output: > > Bindata= 0.00060054 > > So it passed from approx 1.1 to 0.0006 secs. That's quite an improvement! > > Thank you so much. > > Best regards, > David Santiago > > > Ralph Mellor escreveu no dia quarta, > 17/06/2020 à(s) 11:57: >> >>> Unfortunately, i get the error "Error >>> X::AdHoc+{X::Await::Died}+{X::React::Died}: Don't know how many >> elements a C array returned from a library" >> >> I googled the error message and got a bunch of matches including this: >> >> https://stackoverflow.com/questions/51081475/getting-data-out-of-native-pointers >> >> This will show the way to maximize the speed because it minimizes >> the *number* of copy operations (to one) and expense of the copy >> (by making it native code). >> >> hth
Re: Code assertions to spy on regexps behavior
> It doesn't have to be an assertion. Just a code block would do the same. Yes, good point. In the docs, in the section Regex Interpolation, they don't mention that feature, presumably because it literally does no interpolation, but I'd argue that the null case is worth including in this table: SyntaxDescription $variable Interpolates stringified contents of variable literally. $(code) Runs Raku code inside the regex, and interpolates the stringified return value literally. <$variable> Interpolates stringified contents of variable as a regex. <{code}> Runs Raku code inside the regex, and interpolates the stringified return value as a regex. Notably, it is included in Table 4-3 in the Moritz Lenz book "Parsing with Perl 6 Regexes and Grammars": { CODE } Runs Perl 6 code; no effect on regex match On 6/14/20, Vadim Belman wrote: > It doesn't have to be an assertion. Just a code block would do the same. > > Best regards, > Vadim Belman > >> On Jun 14, 2020, at 8:55 PM, Joseph Brenner wrote: >> >> $_ = "Alpha beta gamma"; >> my @matches = m:g/(a) /; > >
Re: interpolating the return from embedded code in a regexp
Brad Gilbert wrote: > You don't want to use <{…}>, you want to use "" > if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / { Well, as contrived examples go this one could be improved. Instead of directly dereferencing a hash, maybe I should've used a sub call. > Note that {} is there to update $/ so that $0 works the way you would expect And notably you really need to know that trick to get that to work, but the direction I was going using <{ ... }> just works without it. I can confirm that the gratuitous code block trick fixes the approach I really thought should work: / (^P\d+) \s+ {} $( %products{$0} ) / This had me wondering if named captures might work differently, but they don't, you still need the {} there: / $=(^P\d+) \s+ {} $( %products{$.Str} ) / > Although I would do something like this instead: > > my ($code,$desc) = $line.split( /\s+/, 2 ); > if %products{$code} eq $desc { Yes, there's other simpler ways... I was just looking for an excuse to try regex code interpolation, particularly when using capture variables in the code... and it does turn out there's an unexpected (to me) gotcha there. On 6/15/20, Brad Gilbert wrote: > You don't want to use <{…}>, you want to use "" > > if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / { > > Note that {} is there to update $/ so that $0 works the way you would > expect > > Although I would do something like this instead: > > my ($code,$desc) = $line.split( /\s+/, 2 ); > if %products{$code} eq $desc { > > On Sun, Jun 14, 2020 at 6:44 PM Joseph Brenner wrote: > >> In part because of the recent discussion here, I decided to >> play around with using Raku code embedded in a regexp. >> I came up with a contrived example where I was going to >> examine a product listing in a text block to see if the product >> descriptions matched the product codes. The valid associations >> I have in a hash, so I'm (1) matching for product codes; (2) >> using embedded code to look-up the associated description in the hash; >> (3) using the returned description inside the regex. >> >> my %products = ( 'P123' => "Green Labels That Say Magenta", >> 'P666' => 'Darkseid For President Bumpersticker', >> 'P912' => "Corn dogs", >> ); >> >> my $text = q:to/END/; >> P123 Viridian Green Label Saying Magenta >> P666 Yoda puppets >> P912 Corn dogs >> END >> >> my @lines = $text.lines; >> say @lines; >> >> for @lines -> $line { >>say "checking line: $line"; >>## This line works, but it's not a complete solution: >>if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> / >> { >>say "Matched, line looks good"; >>} >>else { >>say "NO: bad line."; >>} >> } >> >> I'd thought that a line like this would work: >> >> if $line ~~ / (^P\d+) \s+ <{ %products{$0} }> / { >> >> The trouble though is I've got spaces inside the descriptions, >> so if the returned string is treated as a regexp, I get these >> warnings: >> >>Potential difficulties: >>Space is not significant here; please use quotes or :s >> (:sigspace) modifier (or, to suppress this warning, omit the space, or >> otherwise change the spacing) >> >> Reading a bit, I thought this should work >> >> if $line ~~ / (^P\d+) \s+ $( %products{$0} ) / { >> >> That's supposed to use the return string as a literal match. >> Instead I get a lot of strange messages like: >> >>Use of Nil in string context in regex >> >> Flailing around I considered lots of variations like this: >> >>if $line ~~ / (^P\d+) \s+ Q[<{ %products{$0}}>] / { >> >> But I think that ends up treating everything inside the Q[] >> literally, so you never do the hash lookup. >> >> Another thing that might solve this problem is some sort of >> regexp quote function I could use inside the code before >> returning the string, but I don't know what that would be... >> >
Re: interpolating the return from embedded code in a regexp
On 6/15/20, yary wrote: > The Match docs can be clearer on when to use {} and when it isn't needed, I agree, in fact I'm inclined to think this is an actual bug (design error?). It's pretty strange that the two kinds of code interpolation behave so differently: $(...) requires you to do something to force capture variables are updated, but <{...}> doesn't. Maybe there's a reason you might want to refer to values of $0 from a previous match, but if so why can't you do it from <{...}>, too? > opened an issue https://github.com/Raku/doc/issues/3478 Thanks, see you over there. On 6/15/20, yary wrote: > Brad: "Note that {} is there to update $/ so that $0 works the way you > would expect" > > I ran into that before & was trying to remember that detail... found it in > https://docs.raku.org/language/regexes#Capture_numbers > > But the example is a bit on the obtuse side: > > These capture variables are only available outside the regex. > > # !!WRONG!! The $0 refers to a capture *inside* the second capture > say "11" ~~ /(\d) ($0)/; # OUTPUT: «Nil» > > In order to make them available inside the regex, you need to insert a code > block behind the match; this code block may be empty if there's nothing > meaningful to do: > > # CORRECT: $0 is saved into a variable outside the second capture > # before it is used inside > say "11" ~~ /(\d) {} :my $c = $0; ($c)/; # OUTPUT: «「11」 0 => 「1」 1 => > 「1」» > say "Matched $c"; # OUTPUT: «Matched 1» > > > As of Raku 2019.11 at least, the $0 construct works without the {} code > block, in simple cases. > >> "11" ~~ /(\d) $0/ > > 「11」 > > 0 => 「1」 > >> '876554' ~~ /(\d) $0/ > > 「55」 > > 0 => 「5」 > > > # Inside a new capture, $0 refers to inner capture > >> "11" ~~ /(\d) ($0)/ > > Nil > >> "11" ~~ /(\d) {} ($0)/ > > Nil > >> "11" ~~ /(\d) {} :my $c=$0; ($c)/ > > 「11」 > > 0 => 「1」 > > 1 => 「1」 > # Let's use that inner capture > >> "1122" ~~ /(\d) {} :my $c=$0; ($c (\d) $0)/ > > 「1122」 > > 0 => 「1」 > > 1 => 「122」 > > 0 => 「2」 > > The Match docs can be clearer on when to use {} and when it isn't needed, > opened an issue https://github.com/Raku/doc/issues/3478 > > -y > > > On Mon, Jun 15, 2020 at 3:09 PM Brad Gilbert wrote: > >> You don't want to use <{…}>, you want to use "" >> >> if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / { >> >> Note that {} is there to update $/ so that $0 works the way you would >> expect >> >> Although I would do something like this instead: >> >> my ($code,$desc) = $line.split( /\s+/, 2 ); >> if %products{$code} eq $desc { >> >> On Sun, Jun 14, 2020 at 6:44 PM Joseph Brenner wrote: >> >>> In part because of the recent discussion here, I decided to >>> play around with using Raku code embedded in a regexp. >>> I came up with a contrived example where I was going to >>> examine a product listing in a text block to see if the product >>> descriptions matched the product codes. The valid associations >>> I have in a hash, so I'm (1) matching for product codes; (2) >>> using embedded code to look-up the associated description in the hash; >>> (3) using the returned description inside the regex. >>> >>> my %products = ( 'P123' => "Green Labels That Say Magenta", >>> 'P666' => 'Darkseid For President Bumpersticker', >>> 'P912' => "Corn dogs", >>> ); >>> >>> my $text = q:to/END/; >>> P123 Viridian Green Label Saying Magenta >>> P666 Yoda puppets >>> P912 Corn dogs >>> END >>> >>> my @lines = $text.lines; >>> say @lines; >>> >>> for @lines -> $line { >>>say "checking line: $line"; >>>## This line works, but it's not a complete solution: >>>if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> >>> / >>> { >>>say "Matched, line looks good"; >>>} >>>else { >>>say "NO: bad line."; >>>} >>> } >>> >>> I'd thought that a line like this would work: >>> >>> if $line ~~ / (^P\d+) \s+ <{ %products{$0} }> / { >>> >>> The trouble though is I've got spaces inside the descriptions, >>> so if the returned string is treated as a regexp, I get these >>> warnings: >>> >>>Potential difficulties: >>>Space is not significant here; please use quotes or :s >>> (:sigspace) modifier (or, to suppress this warning, omit the space, or >>> otherwise change the spacing) >>> >>> Reading a bit, I thought this should work >>> >>> if $line ~~ / (^P\d+) \s+ $( %products{$0} ) / { >>> >>> That's supposed to use the return string as a literal match. >>> Instead I get a lot of strange messages like: >>> >>>Use of Nil in string context in regex >>> >>> Flailing around I considered lots of variations like this: >>> >>>if $line ~~ / (^P\d+) \s+ Q[<{ %products{$0}}>] / { >>> >>> But I think that ends up treating everything inside the Q[] >>> literally, so you never do the hash lookup. >>> >>> Another thing that might solve this problem is some sort of >>> regexp quote function I could use inside the code before >>> returning the
Re: interpolating the return from embedded code in a regexp
Just wondering if the docs describe how to access an "inner" capture once saved to a variable? If not maybe the code below would be helpful (from yary's last example, REPL output): > my $capture = "1122" ~~ /(\d) {} :my $c=$0; ($c (\d) $0)/ 「1122」 0 => 「1」 1 => 「122」 0 => 「2」 > say $capture 「1122」 0 => 「1」 1 => 「122」 0 => 「2」 > say ~$capture 1122 > say ~$capture[0] 1 > say ~$capture[1] 122 > say ~$capture[1][0] 2 > say $*VM moar (2020.02.1) HTH, Bill. On Mon, Jun 15, 2020 at 9:42 PM yary wrote: > > Brad: "Note that {} is there to update $/ so that $0 works the way you would > expect" > > I ran into that before & was trying to remember that detail... found it in > https://docs.raku.org/language/regexes#Capture_numbers > > But the example is a bit on the obtuse side: > > These capture variables are only available outside the regex. > > # !!WRONG!! The $0 refers to a capture *inside* the second capture > say "11" ~~ /(\d) ($0)/; # OUTPUT: «Nil» > > In order to make them available inside the regex, you need to insert a code > block behind the match; this code block may be empty if there's nothing > meaningful to do: > > # CORRECT: $0 is saved into a variable outside the second capture > # before it is used inside > say "11" ~~ /(\d) {} :my $c = $0; ($c)/; # OUTPUT: «「11」 0 => 「1」 1 => 「1」» > say "Matched $c"; # OUTPUT: «Matched 1» > > > As of Raku 2019.11 at least, the $0 construct works without the {} code > block, in simple cases. > > > "11" ~~ /(\d) $0/ > > 「11」 > > 0 => 「1」 > > > '876554' ~~ /(\d) $0/ > > 「55」 > > 0 => 「5」 > > > # Inside a new capture, $0 refers to inner capture > > > "11" ~~ /(\d) ($0)/ > > Nil > > > "11" ~~ /(\d) {} ($0)/ > > Nil > > > "11" ~~ /(\d) {} :my $c=$0; ($c)/ > > 「11」 > > 0 => 「1」 > > 1 => 「1」 > > # Let's use that inner capture > > > "1122" ~~ /(\d) {} :my $c=$0; ($c (\d) $0)/ > > 「1122」 > > 0 => 「1」 > > 1 => 「122」 > > 0 => 「2」 > > > The Match docs can be clearer on when to use {} and when it isn't needed, > opened an issue https://github.com/Raku/doc/issues/3478 > > -y > > > On Mon, Jun 15, 2020 at 3:09 PM Brad Gilbert wrote: >> >> You don't want to use <{…}>, you want to use "" >> >> if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / { >> >> Note that {} is there to update $/ so that $0 works the way you would expect >> >> Although I would do something like this instead: >> >> my ($code,$desc) = $line.split( /\s+/, 2 ); >> if %products{$code} eq $desc { >> >> On Sun, Jun 14, 2020 at 6:44 PM Joseph Brenner wrote: >>> >>> In part because of the recent discussion here, I decided to >>> play around with using Raku code embedded in a regexp. >>> I came up with a contrived example where I was going to >>> examine a product listing in a text block to see if the product >>> descriptions matched the product codes. The valid associations >>> I have in a hash, so I'm (1) matching for product codes; (2) >>> using embedded code to look-up the associated description in the hash; >>> (3) using the returned description inside the regex. >>> >>> my %products = ( 'P123' => "Green Labels That Say Magenta", >>> 'P666' => 'Darkseid For President Bumpersticker', >>> 'P912' => "Corn dogs", >>> ); >>> >>> my $text = q:to/END/; >>> P123 Viridian Green Label Saying Magenta >>> P666 Yoda puppets >>> P912 Corn dogs >>> END >>> >>> my @lines = $text.lines; >>> say @lines; >>> >>> for @lines -> $line { >>>say "checking line: $line"; >>>## This line works, but it's not a complete solution: >>>if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> / { >>>say "Matched, line looks good"; >>>} >>>else { >>>say "NO: bad line."; >>>} >>> } >>> >>> I'd thought that a line like this would work: >>> >>> if $line ~~ / (^P\d+) \s+ <{ %products{$0} }> / { >>> >>> The trouble though is I've got spaces inside the descriptions, >>> so if the returned string is treated as a regexp, I get these >>> warnings: >>> >>>Potential difficulties: >>>Space is not significant here; please use quotes or :s >>> (:sigspace) modifier (or, to suppress this warning, omit the space, or >>> otherwise change the spacing) >>> >>> Reading a bit, I thought this should work >>> >>> if $line ~~ / (^P\d+) \s+ $( %products{$0} ) / { >>> >>> That's supposed to use the return string as a literal match. >>> Instead I get a lot of strange messages like: >>> >>>Use of Nil in string context in regex >>> >>> Flailing around I considered lots of variations like this: >>> >>>if $line ~~ / (^P\d+) \s+ Q[<{ %products{$0}}>] / { >>> >>> But I think that ends up treating everything inside the Q[] >>> literally, so you never do the hash lookup. >>> >>> Another thing that might solve this problem is some sort of >>> regexp quote function I could use inside the code before >>> returning the string, but I don't know what that would be...
Re: interpolating the return from embedded code in a regexp
Hi Joe, 1. I got your first "if" line (below) from June 14th to work, the one you said, "it's not a complete solution": 1> if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> / { 2. I got Brad's "if" line (below) from June 15th to work: 2> if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / { 3. However, I couldn't get the {}-updated "if" line (below) you posted from June 17th to work: 3> if / (^P\d+) \s+ {} $( %products{$0} ) / { 4. Nor could I get your named-capture "if" line (below) from June 17th to work: 4> if / $=(^P\d+) \s+ {} $( %products{$.Str} ) / { By "works", I mean that the third "Corn dogs" example matches, while the first two fail: checking line: P123 Viridian Green Label Saying Magenta NO: bad line. checking line: P666 Yoda puppets NO: bad line. checking line: P912 Corn dogs Matched, line looks good "This is Rakudo version 2020.02.1..1 built on MoarVM version 2020.02.1 implementing Raku 6.d." HTH, Bill. On Wed, Jun 17, 2020 at 1:13 PM Joseph Brenner wrote: > > Brad Gilbert wrote: > > You don't want to use <{…}>, you want to use "" > > > if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / { > > Well, as contrived examples go this one could be > improved. Instead of directly dereferencing a > hash, maybe I should've used a sub call. > > > Note that {} is there to update $/ so that $0 works the way you would expect > > And notably you really need to know that trick to > get that to work, but the direction I was > going using <{ ... }> just works without it. > > I can confirm that the gratuitous code block trick fixes > the approach I really thought should work: > >/ (^P\d+) \s+ {} $( %products{$0} ) / > > This had me wondering if named captures might work > differently, but they don't, you still need the {} > there: > >/ $=(^P\d+) \s+ > {} > $( %products{$.Str} ) / > > > > Although I would do something like this instead: > > > > my ($code,$desc) = $line.split( /\s+/, 2 ); > > if %products{$code} eq $desc { > > Yes, there's other simpler ways... I was just > looking for an excuse to try regex code > interpolation, particularly when using capture > variables in the code... and it does turn out > there's an unexpected (to me) gotcha there. > > > On 6/15/20, Brad Gilbert wrote: > > You don't want to use <{…}>, you want to use "" > > > > if $line ~~ / (^P\d+) \s+ {} "%products{$0}" / { > > > > Note that {} is there to update $/ so that $0 works the way you would > > expect > > > > Although I would do something like this instead: > > > > my ($code,$desc) = $line.split( /\s+/, 2 ); > > if %products{$code} eq $desc { > > > > On Sun, Jun 14, 2020 at 6:44 PM Joseph Brenner wrote: > > > >> In part because of the recent discussion here, I decided to > >> play around with using Raku code embedded in a regexp. > >> I came up with a contrived example where I was going to > >> examine a product listing in a text block to see if the product > >> descriptions matched the product codes. The valid associations > >> I have in a hash, so I'm (1) matching for product codes; (2) > >> using embedded code to look-up the associated description in the hash; > >> (3) using the returned description inside the regex. > >> > >> my %products = ( 'P123' => "Green Labels That Say Magenta", > >> 'P666' => 'Darkseid For President Bumpersticker', > >> 'P912' => "Corn dogs", > >> ); > >> > >> my $text = q:to/END/; > >> P123 Viridian Green Label Saying Magenta > >> P666 Yoda puppets > >> P912 Corn dogs > >> END > >> > >> my @lines = $text.lines; > >> say @lines; > >> > >> for @lines -> $line { > >>say "checking line: $line"; > >>## This line works, but it's not a complete solution: > >>if $line ~~ / (^P\d+) \s+ <{ %products{$0}.subst(/\s+/, '\s', :g) }> / > >> { > >>say "Matched, line looks good"; > >>} > >>else { > >>say "NO: bad line."; > >>} > >> } > >> > >> I'd thought that a line like this would work: > >> > >> if $line ~~ / (^P\d+) \s+ <{ %products{$0} }> / { > >> > >> The trouble though is I've got spaces inside the descriptions, > >> so if the returned string is treated as a regexp, I get these > >> warnings: > >> > >>Potential difficulties: > >>Space is not significant here; please use quotes or :s > >> (:sigspace) modifier (or, to suppress this warning, omit the space, or > >> otherwise change the spacing) > >> > >> Reading a bit, I thought this should work > >> > >> if $line ~~ / (^P\d+) \s+ $( %products{$0} ) / { > >> > >> That's supposed to use the return string as a literal match. > >> Instead I get a lot of strange messages like: > >> > >>Use of Nil in string context in regex > >> > >> Flailing around I considered lots of variations like this: > >> > >>if $line ~~ / (^P\d+) \s+ Q[<{ %products{$0}}>] / { > >> > >> But I think that ends up treating everything inside the Q[] > >> literall