Let's use "trans" instead of a regular expression, updating my example:

sub format-string(Str:D $source, *%vars  --> Str:D) {
    return $source.trans(
        [%vars.keys.map: '$(' ~ * ~ ')' ] => [%vars.values]
      );
}

so simple! But, it does not catch missing variables... I bet we can fix
that by adding a regexp at the end... and also test if multi-substitution
happens. Ah it all works nicely as I would like.

#!/usr/bin/env perl6

my Str $source = '$(greeting), $(name). What do you think about
$(any-topic)?';

my Str $output = format-string(
        $source,
        name => 'Earthling [$(any-topic)=should say "any-topic"]',
        any-topic => '[$(name)=should say "name"] life on other planets',
    );

say $output;  # I don't know your greeting, Earthling [$(any-topic)=should
say "any-topic"]. What do you think about [$(name)=should say "name"] life
on other planets?

sub format-string(Str:D $source, *%vars  --> Str:D) {
    return $source.trans(
        [%vars.keys.map( '$(' ~ * ~ ')' ),
          / '$(' ( <[\w -]>+ ) ')' / ]
          => [ %vars.values,
               { "I don't know your $0" }
             ]
      );
}


-y


On Wed, Aug 29, 2018 at 1:41 PM Patrick Spek via perl6-users <
perl6-us...@perl.org> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
>
> It's supposed to be simple, since I don't need much. The most basic of
> substitution is all I care about right now. I've implemented it with a
> simple regex now, and it seems to work just fine. It's available as a
> module[1] now, and it's used in another module of mine[2]. If anybody
> wants to improve it, feel free to submit a MR on the repository[3].
>
> Thanks everyone for your help!
>
> [1]: https://modules.perl6.org/dist/I18n::Simple:cpan:TYIL
> [2]: https://gitlab.com/tyil/perl6-app-assixt
> [3]: https://gitlab.com/tyil/perl6-i18n-Simple
>
> On Wed, 29 Aug 2018 19:28:56 +0200
> Timo Paulssen <t...@wakelift.de> wrote:
>
> > I should point out that the trans method has a mode that lets you pass
> > placeholders and substitutions and it will Do The Right Thing
> > regarding overlaps and order and everything.
> >
> >
> > On 29/08/18 16:21, Timo Paulssen wrote:
> > > There's a problem with your code, if any of the substitutions
> > > contains something that looks like the placeholder thing, and if it
> > > comes later in the iteration of the hash keys (which is randomized
> > > now) it will substitute again. This is very likely not what you
> > > want, though.
> > >
> > > HTH
> > >   - Timo
> > >
> > > On 28/08/18 20:04, Laurent Rosenfeld via perl6-users wrote:
> > > > Hi Patrick, > > for note that this codeline: > > my Str $input =
> > > > "Here be a
> > > $(placeholder), for $(purpose) purposes."; > > will not compile
> > > because Perl will try to interpolate $(placeholder) and $(purpose)
> > > as vairables that have not been declared. > > You need to use non
> > > interpolating quotes: > > my Str $input = 'Here be a $(placeholder),
> > > for $(purpose) purposes.'; > > Then, I would probably use simple
> > > substitutions, as with this example: > > my Str $input = 'Here be a
> > > $(placeholder), for $(purpose) purposes.'; > > sub format-string
> > > ($input, %substitutions) { > my $str = $input; > for keys
> > > %substitutions -> $key { > $str ~~ s/$key/%substitutions{$key}/;
> > > > } > return $str; > } > my %substitutes = '$(placeholder)' =>
> > > "placeholder", '$(purpose)' => "testing"; > my $output =
> > > format-string($input, %substitutes); > say $output; > > This is the
> > > output running this under the REPL: > > > my Str $input = 'Here be a
> > > $(placeholder), for $(purpose) purposes.'; > Here be a
> > > $(placeholder), for $(purpose) purposes. > > > > sub format-string
> > > ($input, %substitutions) { > * my $str = $input; > * for keys
> > > %substitutions -> $key { > * $str ~~ s/$key/%substitutions{$key}/;
> > > > * } > * return $str; > * } > sub format-string ($input,
> > > > %substitutions) {
> > > #`(Sub|214745424) ... } > > my %substitutes = '$(placeholder)' =>
> > > "placeholder", '$(purpose)' => "testing"; > {$(placeholder) =>
> > > placeholder, $(purpose) => testing} > > my $output =
> > > format-string($input, %substitutes); > Here be a placeholder, for
> > > testing purposes. > > say $output; > Here be a placeholder, for
> > > testing purposes. > > I hope this helps. > > Cheers, > Laurent. > >
> > > >
> > > > > Le mar. 28 août 2018 à 12:25, Patrick Spek via perl6-users
> > > <perl6-us...@perl.org <mailto:perl6-us...@perl.org>> a écrit : >
> > >> Hi all,
> > >>
> > >> I'm trying to substitute parts of a string, and thought this might
> > >> be a good use of a grammar. Sadly, grammars aren't my strong suit,
> > >> so I thought I'd ask the wider community for help. Maybe you guys
> > >> know an even better solution than using a grammar here.
> > >>
> > >> So, consider a string, "Here be a $(placeholder), for $(purpose)
> > >> purposes.". I want to be able to put that into a sub, along with
> > >> some Pairs, and get a string with the placeholders replaced back.
> > >>
> > >>     my Str $input = "Here be a $(placeholder), for $(purpose)
> > >> purposes."; my Str $output = format-string(
> > >>         $input,
> > >>         placeholder => "placeholder",
> > >>         purpose => "testing",
> > >>     );
> > >>
> > >>     dd $output; # "Here be a placeholder, for testing purposes."
> > >>
> > >> The `format-string` sub would call the grammar and apply the actual
> > >> substitution, and that's where I need your help. I am not quite
> > >> sure how I would implement the grammar (and presumably it's
> > >> actions) to do what I want.
> > >>
> > >> Thanks in advance for your help!
> > >>
> > > >
> > >
> >
>
>
>
> - --
> With kind regards,
>
> Patrick Spek
>
>
> www:  https://www.tyil.work/
> mail: p.s...@tyil.nl
> pgp:  EB9E A484 1672 2D37 16F5  A799 9ACF E193 FFBC 1F50
>
> mastodon: @tyil@mastodon.social
> github:   @Tyil
> gitlab:   @tyil
>
> -----BEGIN PGP SIGNATURE-----
>
> iQEzBAEBCAAdFiEE4eL662U9iK2ST2MqN/W6H45XOE8FAluHBKQACgkQN/W6H45X
> OE8I/wf/YWLWKCxj0AUvJt9xaosRPYYw2A3z8IgejA95S6UjeIgCzswal3xp0YiU
> FfkUL0eSiuXc2fw3FLFl/FK0R6KzpW8V+kBpKZaB0bcU9tErpwTYwLQFyxvdgYjQ
> FUiCZ+sM6963RihCJZwVMF8pzwZDOcKMmuxg67Ufd/syOHE7yZT2MV8FxXAA0xAT
> pGRA00XrlSIzJTY1VQcWY5JjrbM+aD9U/QsfWiVc8oKrbAKGExJ096UQ3bcDhFzf
> EwMhdGBUrkQjfGj7TPWhC9w2fmth+DiNx2EhSYZCKs7Qn0+XmaOMsznC6/Dm23sv
> ok27sdgL+jr/P0x1CjrpAlxX5jgJiA==
> =fDhH
> -----END PGP SIGNATURE-----
>

Reply via email to