Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concatenate -e flags in CLI before eval #1089

Merged
merged 1 commit into from
Feb 14, 2021
Merged

Concatenate -e flags in CLI before eval #1089

merged 1 commit into from
Feb 14, 2021

Conversation

lopopolo
Copy link
Member

MRI Ruby's CLI can run multiple -e commands even when individual commands have malformed syntax:

$ ruby -e '2.times {' -e 'puts "foo: #{__LINE__}"' -e '}'
foo: 2
foo: 2

Artichoke's CLI currently evals each -e command one at a time and manually increments the parser line number. This same set of commands fails with a syntax error:

$ cargo -q run --bin artichoke -- -e '2.times {' -e 'puts "foo"' -e '}'
syntax error (SyntaxError)

With this patch, Artichoke's Ruby CLI frontend collects all given -e commands into a single OsString, separating each command with a newline. This results in the correct behavior:

$ cargo -q run --bin artichoke -- -e '2.times {' -e 'puts "foo: #{__LINE__}"' -e '}'
foo: 2
foo: 2

MRI Ruby's CLI can run multiple `-e` commands even when individual
commands have malformed syntax:

```console
$ ruby -e '2.times {' -e 'puts "foo: #{__LINE__}"' -e '}'
foo: 2
foo: 2
```

Artichoke's CLI currently evals each `-e` command one at a time and
manually increments the parser line number. This same set of commands
fails with a syntax error:

```console
$ cargo -q run --bin artichoke -- -e '2.times {' -e 'puts "foo"' -e '}'
syntax error (SyntaxError)
```

With this patch, Artichoke's Ruby CLI frontend collects all given `-e`
commands into a single `OsString`, separating each command with a
newline. This results in the correct behavior:

```console
$ cargo -q run --bin artichoke -- -e '2.times {' -e 'puts "foo: #{__LINE__}"' -e '}'
foo: 2
foo: 2
```
@lopopolo lopopolo added C-bug Category: This is a bug. A-frontend Area: Frontends for interpreters, like the `ruby` or `irb` binaries. labels Feb 14, 2021
@lopopolo lopopolo merged commit fe60f65 into trunk Feb 14, 2021
@lopopolo lopopolo deleted the cli-e-flag-concat branch February 14, 2021 23:04
@lopopolo lopopolo restored the cli-e-flag-concat branch February 14, 2021 23:04
@lopopolo lopopolo deleted the cli-e-flag-concat branch February 14, 2021 23:04
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Mar 14, 2021
…=joshtriplett

Implement Extend and FromIterator for OsString

Add the following trait impls:

- `impl Extend<OsString> for OsString`
- `impl<'a> Extend<&'a OsStr> for OsString`
- `impl FromIterator<OsString> for OsString`
- `impl<'a> FromIterator<&'a OsStr> for OsString`

Because `OsString` is a platform string with no particular semantics, concatenating them together seems acceptable.

I came across a use case for these trait impls in artichoke/artichoke#1089:

Artichoke is a Ruby interpreter. Its CLI accepts multiple `-e` switches for executing inline Ruby code, like:

```console
$ cargo -q run --bin artichoke -- -e '2.times {' -e 'puts "foo: #{__LINE__}"' -e '}'
foo: 2
foo: 2
```

I use `clap` for command line argument parsing, which collects these `-e` commands into a `Vec<OsString>`. To pass these commands to the interpreter for `Eval`, I need to join them together. Combining these impls with `Iterator::intersperse` rust-lang#79524 would enable me to build a single bit of Ruby code.

Currently, I'm doing something like:

```rust
let mut commands = commands.into_iter();
let mut buf = if let Some(command) = commands.next() {
    command
} else {
    return Ok(Ok(()));
};
for command in commands {
    buf.push("\n");
    buf.push(command);
}
```

If there's interest, I'd also like to add impls for `Cow<'a, OsStr>`, which would avoid allocating the `"\n"` `OsString` in the concatenate + intersperse use case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: Frontends for interpreters, like the `ruby` or `irb` binaries. C-bug Category: This is a bug.
Development

Successfully merging this pull request may close these issues.

None yet

1 participant