Open bar-g opened 8 months ago
Maybe something with &places ?
main='a'
sub='b'
local $main$sub='value'
echo ab=$ab # ab=value
I think the main one would be evalExpr()
, and that's now implemented
So you can do evalExpr('my' ++ 'var')
and it gives the value of looking up that variable name
I can add a couple words there
Hmm actually I realized evalExpr()
is for YSH expressions, but really we would need something for these Bourne shell expressions
${!indirect}
It's actually similar to what test -v
does, there is dynamic parsing of a[0]
and so forth
I guess I can can change it to a TODO in the doc ... Hopefully some user of ${!indirect}
will see that
Well, I'd like to avoid that implicit parsing in ${...}, also therefore looking for a safe way of indirect variable access (for 1. read and 2. write) in ysh.
Can't seem to make evalExpr work for reading vars, though.
ysh ysh-0.19.0$ ab=foo
ysh ysh-0.19.0$ echo $[evalExpr('a' ++ 'b')]
echo $[evalExpr('a' ++ 'b')]
^~
[ interactive ]:99: fatal: Arg 1 should be a Expr, got Str
Ah good point, yeah you need a value.Expr
quotation type which is ^[...]
But that means "a" ++ "b"
doesn't really work
OK we should change it to also accept a string. Just like now eval 'echo cmd'
accepts a string but also a value.Command
quotation type
And maybe make sure to have some examples for
var x = 5
var s1 = "echo x = $x"
var s2 = ^"echo x = $x" # or ^["echo x = $x"]
setvar x = 10
echo $[evalExpr(s1)]
-> x = 5
echo $[evalExpr(s2)]
-> echo x = 10 # i hope that's correct? or is it "x = 10"?
Hm, with me originally looking for a safe way for variable (name) indirection, I'm not sure if using the full eval fuctionality is desired for that.
IIUC ${!...} was once meant as a safer replacement instead of using eval, but apparently failed in doing so in bash due to the extensive parsing that includes execution. So ${!...} is not advisable to use, even though safer (only) in osh and ysh due to eval_unsafe_arith being disabled by default.
So, taking a step back, it's probably advisable to only use the provided structured ysh data types instead (list/dict). And consequently, for the ${!indirect} mention in the ysh-tour doc, maybe it could or should simply point to replace it with, e.g.:
var d2 = {[key ++ '_z']: 'ZZZ'} # Computed key name
echo $[d2.alice_z] # => ZZZ # Reminder: expression sub
Hm, but a remaining question from me would be how to use a "computed key" for data output, e.g. in an expression sub.
Is this correct?: (but not implemented, yet)
osh-0.19.0$ echo $[d->get("$a$b")]
echo $[d->get("$a$b")]
^~~
[ interactive ]:45: fatal: Method 'get' does not exist on type Dict
You can use d["$a$b"]
, which will raise an exception like Python if it doesn't exist
I think d => get("$a$b")
is not implemented yet, which will return null
like Python, should do that
We made a change recently where ->
is for mutating methods and =>
is for transforming methods, though it's not completely enforced yet
Thanks! Looking forward if the most basic set of dict access is actually possible already. But it's a bit unfortunate, that I wasn't able to get these from the current docs though.
See, I don't fit to this slogan: YSH is for Python and JavaScript users who avoid shell!
So maybe something like this could also be considered?: YSH is also for users of ordinary shells which want to work efficiently also with other data types than lines of words, and without having to continuously drag around a bag of pitfall workarounds for every task.
In this vein, I'd like to suggest, re-adding the mention of bash's ${!indirect} to the ysh-tour doc again. For example, with something like this:
- Most of what's in `${}` has *more readable and safer* alternatives. For example
- `"${s#/tmp}"` could be `s => removePrefix('/tmp')` (TODO).
- `"${!indirect}"` could be `$[mydict["$mykey"]]` (shorter: $[mydict[mykey]]), or mydict=>get(mykey) (returns null insted of error).
Bumping this bug, it came up again - https://oilshell.zulipchat.com/#narrow/stream/417617-help-wanted/topic/evalExpr.28.29.20should.20accept.20a.20string.20too
I read ${!indirect} is deprecated in https://www.oilshell.org/release/latest/doc/ysh-tour.html but could not find any idea how variable indirection is done properly in ysh.
for variable substitutions? instead of echo ${!a}, i.e. how to use variable named like some "$composable$string"
for assignments setvar $main$sub = "value" ?