-
Notifications
You must be signed in to change notification settings - Fork 247
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
Named parameters break if the function returns immediately after parameter definition #41
Comments
Indeed, this is a serious problem. It looks like this: # syntax with commas:
function example { args : @required string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
# syntax with colons and new lines:
function example {
args
: @required string firstName
: string lastName
: integer age
: string[] ...favoriteHobbies
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
echo "My favorite hobbies include: ${favoriteHobbies[*]}"
}
# normal usage:
example Mark McDonald 32 singing jumping Try playing around with this snippet and feel free to give me your feedback: #!/usr/bin/env bash
shopt -s expand_aliases
function echo_stderr {
echo "$*" >&2
}
function assignTrap {
local evalString
local -i paramIndex=${__paramIndex-0}
local initialCommand="${1-}"
if [[ "$initialCommand" != ":" ]]
then
echo "trap - DEBUG; eval \"${__previousTrap}\"; unset __previousTrap; unset __paramIndex;"
return
fi
while [[ "${1-}" == "," || "${1-}" == "${initialCommand}" ]] || [[ "${#@}" -gt 0 && "$paramIndex" -eq 0 ]]
do
shift # first colon ":" or next parameter's comma ","
paramIndex+=1
local -a decorators=()
while [[ "${1-}" == "@"* ]]
do
decorators+=( "$1" )
shift
done
local declaration=
local wrapLeft='"'
local wrapRight='"'
local nextType="$1"
local length=1
case ${nextType} in
string | boolean) declaration="local " ;;
integer) declaration="local -i" ;;
reference) declaration="local -n" ;;
arrayDeclaration) declaration="local -a"; wrapLeft= ; wrapRight= ;;
assocDeclaration) declaration="local -A"; wrapLeft= ; wrapRight= ;;
"string["*"]") declaration="local -a"; length="${nextType//[a-z\[\]]}" ;;
"integer["*"]") declaration="local -ai"; length="${nextType//[a-z\[\]]}" ;;
esac
if [[ "${declaration}" != "" ]]
then
shift
local nextName="$1"
local handleless=
for decorator in "${decorators[@]}"
do
case ${decorator} in
@readonly) declaration+="r" ;;
@required) evalString+="[[ ! -z \$${paramIndex} ]] || echo_stderr \"Parameter '$nextName' ($nextType) is marked as required by '${FUNCNAME[1]}' function.\"; " ;;
@handleless) handleless=1 ;;
@global) declaration+="g" ;;
esac
done
local paramRange="$paramIndex"
if [[ -z "$length" ]]
then
# ...rest
paramRange="{@:$paramIndex}"
# trim leading ...
nextName="${nextName//\./}"
if [[ "${#@}" -gt 1 ]]
then
echo_stderr "Unexpected arguments after a rest array ($nextName) in '${FUNCNAME[1]}' function."
fi
elif [[ "$length" -gt 1 ]]
then
paramRange="{@:$paramIndex:$length}"
paramIndex+=$((length - 1))
fi
evalString+="${declaration} ${nextName}=${wrapLeft}\$${paramRange}${wrapRight}; "
# if [[ "$handleless" != 1 ]]
# then
# evalString+="Type::CreateHandlerFunction \"$nextName\"; "
# fi
# continue to the next param:
shift
fi
done
# echo_stderr "evaling $evalString"
echo "${evalString} local -i __paramIndex=${paramIndex};"
}
alias args='local __previousTrap=$(trap -p DEBUG); trap "eval \"\$(assignTrap \$BASH_COMMAND)\";" DEBUG;'
# syntax with commas:
function example { args : @required string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
}
# syntax with colons and new lines:
function example {
args
: @required string firstName
: string lastName
: integer age
: string[] ...favoriteHobbies
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
echo "My favorite hobbies include: ${favoriteHobbies[*]}"
}
example Mark McDonald 32 singing jumping |
This line missing from the current version had me spending 3 hours of going through thousands of There is also the issue of the I find this implementation to be awesome! I cannot decide if I like the new syntax more or not. I would still like to explore the possibility of having the old aliases work. My only objection is the comma syntax. I think it breaks the bash function "signature", ie instead of [function] func_name[()] {.*} we now have: [function] func_name[()] {.*}{.*} This might break existing tools that rely on the first "signature" to scan the code and identify function definitions, etc. |
Thanks for the feedback! I think old aliases could be ported - I was thinking how to do it and it shouldn't be too hard to add. As for the comma signature, it shouldn't break. Here's why: the second function example {
args : @required string firstName , string lastName , integer age } {
echo "My name is ${firstName} ${lastName} and I am ${age} years old."
} The curly braces really just there as a decoration, as they're ignored by At least when I've tried with shellcheck, it worked. No idea about how it might work with |
Consider this example bash file:
In the above example, there is no command for the DEBUG trap to hook into. This is expected.
Now consider this:
In the above, (it seems that) the
var
array will be set when thefor i in "${var[@]}"; do
line gets run. But bash will not even run this line as there is no array to expand. So, it will simply skip the loop and return from the function as there is no other command to run. As a result, the context will change and__assign_paramNo
and the other variables will be unset. The@required
is there just for the example, it is not crucial to repeating the behavior. If there were more lines after the loop in the function, bash would still skip the loop, but the array would eventually be evaluated when the line after the loop was run.I haven't found a way to solve this.
The text was updated successfully, but these errors were encountered: