Perl support in Liquidprompt
Tags: liquidprompt, pr, 24prs, opensource
Published: 2023-12-02 11:13:12

---
title: Perl support in Liquidprompt
published: true
description: following up on a 7 year old unmerged PR
tags: liquidprompt, pr, 24prs, opensource
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-12-02 11:11 +0000
---
A long long time ago I fell over [Liquidprompt](https://liquidprompt.readthedocs.io/en/stable/) and I used it for a long time, running on my own fork, which had support for [perlbrew](https://perlbrew.pl/) implemented by me, nothing like scratching your own itch.

Back in the day I sent [a pull request](https://github.com/liquidprompt/liquidprompt/pull/439) to the original author, but it was never merged, I had some dialogue with the new maintainer, but never got around to porting the code to the latest version of **Liquidprompt**.

Now that I decided to join the [24 PRs](https://24pullrequests.com/), I decided to give it another go.

So here it is, [a PR](https://github.com/liquidprompt/liquidprompt/pull/812) with a new implementation of **Perlbrew** support to the latest version of **Liquidprompt** and as a bonus, I also added support for [plenv](https://github.com/tokuhirom/plenv) and alternative to **Perlbrew** for handling your Perl installations.

One interesting part I want to highlight is this Bash thing. I had to get GitHub co-pilot to explain it to me.

**plenv** resembles **rbenv** so I could basically reuse the implementation of **rbenv**. The two emit a somewhat similar string:

```shell
rbenv version
3.2.2 (set by /Users/jonasbn/.rbenv/version)
```

```shell
plenv
5.10.1 (set by /Users/jonasbn/.plenv/version)
```

And these can be handled by a Bash contruct like this:

```bash
"${plenv_ver%%" (set"*}"
```

**Perlbrew** however emits version strings like so:

```shell
perlbrew use
Currently using perl-5.38.0
```

So I needed to get my head around: `%%` and I needed something along those lines, but removing part of the string, isolating the version string.

I found this Bash [documentation][BASH] and a marvellous [question](https://unix.stackexchange.com/questions/576871/in-bash-trailing-space-capture-in-variable-substitution) with a some goood examples which could be used to speed up the implementation, since it could be done on the command line using Bash.

The operator is called: `##` and it is used for removing a prefix pattern, where `%%` is used for removing a suffix pattern.

And in Bash you can do something along the following to test your code faster:

```bash
perlbrew_perl_ver="Currently using perl-5.38.0" && echo "${perlbrew_perl_ver##}"
```

I did that and kept adding to the pattern until I got the result I wanted and I ended up with this implementation:

```bash
"${perlbrew_perl_ver##*perl-}"
```

From the [documentation][BASH] for: `%%` used for `plenv` and `rbenv`:

> ${parameter%%word} 
> Remove matching suffix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ''%'' case) or the longest matching pattern (the ''%%'' case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

And for `##` used in my own implementation for `perlbrew`:

> ${parameter##word}
> Remove matching prefix pattern. The word is expanded to produce a pattern just as in pathname expansion. If the pattern matches the beginning of the value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ''#'' case) or the longest matching pattern (the ''##'' case) deleted. If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with @ or *, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

This was quite a journey down a rabbit hole, but I got it too work eventually.

## Additional resources

- Liquidprompt on [github](https://github.com/liquidprompt/liquidprompt)
- Perlbrew on [github](https://github.com/gugod/App-perlbrew)
- Perlbrew on [CPAN](https://metacpan.org/pod/App::perlbrew)
- Perlbrew website [perlbrew.pl](https://perlbrew.pl/)

[BASH]: https://linux.die.net/man/1/bash