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

Allow $env and mutable records to be mutated by = (closes #7110) #7318

Merged
merged 2 commits into from
Dec 6, 2022

Conversation

webbedspace
Copy link
Contributor

@webbedspace webbedspace commented Dec 2, 2022

Description

Closes #7110. Note that unlike "real" mut vars, $env can be deeply mutated via stuff like $env.PYTHON_IO_ENCODING = utf8 or $env.config.history.max_size = 2000. So, it's a slightly awkward special case, arguably justifiable because of what $env represents (the environment variables of your system, which is essentially "outside" normal Nushell regulations).
EDIT: Now allows all mut vars to be deeply mutated using =, on request.

User-Facing Changes

See above.

Tests + Formatting

Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

  • cargo fmt --all -- --check to check standard code formatting (cargo fmt --all applies these changes)
  • cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect to check that you're using the standard code style
  • cargo test --workspace to check that all tests pass

After Submitting

If your PR had any user-facing changes, update the documentation after the PR is merged, if necessary. This will help us keep the docs up to date.

@fdncred
Copy link
Collaborator

fdncred commented Dec 2, 2022

really love the idea of being able to change config settings so easily.

@kubouch
Copy link
Contributor

kubouch commented Dec 2, 2022

I like the idea but I don't like special-casing $env. I think we could allow = to upsert instead of update for all variables. And/or implement the |= operator proposed by JT: $env |= upsert PYTHON_IO_ENCODING utf8. Anyway, this feels like a language design question that should be discussed more carefully.

@ChrisDenton
Copy link
Contributor

But $env is kinda special, no? As noted somewhere, the environment is largely an OS concept rather than something nushell. Or at the least it has special platform-specific considerations. Which is not to say it $env should work differently, just that working differently may be justified.

@kubouch
Copy link
Contributor

kubouch commented Dec 2, 2022

From the language point of view $env is just a variable, a record, like $nu, for example. We could treat it as if it was defined with mut env = ... instead of let env = ... which I'm totally fine with but this PR also suggests a specific language extension that applies only to $env. Special cases increase mental overhead when learning the language and also add extra maintenance effort. Sometimes, there is a good reason to introduce a special case, but in this case I believe we don't need one.

@Kangaxx-0
Copy link
Contributor

I like the idea but I don't like special-casing $env. I think we could allow = to upsert instead of update for all variables. And/or implement the |= operator proposed by JT: $env |= upsert PYTHON_IO_ENCODING utf8. Anyway, this feels like a language design question that should be discussed more carefully.

Are you saying this part ?
image

@kubouch
Copy link
Contributor

kubouch commented Dec 3, 2022

@webbedspace We discussed this a bit and it seems like we could support adding new record fields with =. So, you should be able to do mut rec = { a: 10 }; $rec.b = 20. If you could change this PR to allow that for all variables without special-casing $env, we could merge it.

Also, it would need tests.

@webbedspace
Copy link
Contributor Author

@webbedspace We discussed this a bit and it seems like we could support adding new record fields with =. So, you should be able to do mut rec = { a: 10 }; $rec.b = 20. If you could change this PR to allow that for all variables without special-casing $env, we could merge it.

Also, it would need tests.

OK, I've now done all that. Note that I had to do a number of non-trivial tweaks in order to make mutable lists like mut a = {a:[0]}; $a.a.1 = 1 work correctly.

@fdncred
Copy link
Collaborator

fdncred commented Dec 4, 2022

I'm not sure how others will feel about these changes but I'm loving playing in this PR. I love how it makes changing things so easy. The only thing that took me by surprise was the ability to mutate the next indexed element. Example:

> mut a = [0 1 2]
> # Test to see if $a.3 exists
> $a.3
Error: nu::shell::access_beyond_end (link)

  × Row number too large (max: 2).
   ╭─[entry #2:1:1]
 1 │ $a.3
   ·    ┬
   ·    ╰── index too large (max: 2)
   ╰────

> # Append by indexing into a non-existent next index
> $a.3 = 3
> $a
╭───┬───╮
│ 0 │ 0 │
│ 1 │ 1 │
│ 2 │ 2 │
│ 3 │ 3 │
╰───┴───╯

> # Test if you can skip an index
> $a.5 = 5
Error: nu::shell::access_beyond_end (link)

  × Inserted at wrong row number (should be 4).
   ╭─[entry #43:1:1]
 1 │ $a.5 = 5
   ·    ┬
   ·    ╰── can't insert at index (the next available index is 4)
   ╰────

I mean, I could live with this and I think it's kind of cool, but it took me by surprise.

@webbedspace
Copy link
Contributor Author

webbedspace commented Dec 5, 2022

That's what I had to do to take the concept of "mutating via insert", which already exists for records, and "make it make sense" for lists. In Javascript, of course, you can just do a = [0]; a[1000] = 1 and it "works", but the gap creates 998 "holes" (similar to Nushell table holes), and since those don't exist for Nushell lists (and Rust vecs) I had to add that restriction and error message.

EDIT: Forgot to mention, this is also how upsert currently works: try [0] | upsert 1 'foo'

@kubouch kubouch changed the title Allow $env to be mutated by = as if it was mutable (closes #7110) Allow $env and mutable variables to be mutated by = (closes #7110) Dec 6, 2022
@kubouch kubouch changed the title Allow $env and mutable variables to be mutated by = (closes #7110) Allow $env and mutable records to be mutated by = (closes #7110) Dec 6, 2022
@kubouch
Copy link
Contributor

kubouch commented Dec 6, 2022

OK, looks good, let's try it. Thanks!

@kubouch kubouch merged commit 9b41f9e into nushell:main Dec 6, 2022
@webbedspace webbedspace deleted the env-mutation branch December 7, 2022 04:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mutation of $env using cell paths doesn't seem to work
5 participants