-
Notifications
You must be signed in to change notification settings - Fork 1
endlocal extension #46
Comments
Actually, the best way to transfer an environment variable across the ENDLOCAL barrier is to use a global heap variable! I would structure the return as follows (the complexity is to guarantee safe return of any value, and no side effects)
But that is more code than I want to write. I would like a But I would have it take pairs of arguments, plus an optional return code, as in
|
Possible duplicate on: #32 (comment) |
Copy heap global variable to environment block for allow return values I thinks is not good.
That is a litte bit better than the proposed single responsability endlocal extension, because is not needed write parenthesis for have the value after the endlocal, copied in the parenthesis block, and now that I'm think it again, is good that the endlocal restore all, else you will get in the parent context with possible changed delayed expansion option. @adoxa Jason. I think this can be implemented as this: |
Goto :eof won't work, as that occurs before EndLocal. Having calls automatically create local heap variables and providing a syntax to get/set global/parent heap variables is far easier for me to implement. Perhaps something like: :sub
:: declare global variables
call @global $global
:: declare parent variables
call @caller $return
:: everything else is local to :sub |
Good idea Jason, but I have doubt about the concept of declaration, because in batch always is needed set a value. Thus, is missed the value?. About GLOBAL I think is more simple continue with the global heap variable prefixed with $. About CALLER, what about name it INVSET as brief of invoker set, this can use the same syntax of set. Other option I think can be better is create a specialized extension SET where you can indicate options, for example the concept of type.
|
The declaration is for the scope of the variable, not its value. Maybe OUT would be better than CALLER. set $global=global
set $local=local
set $return=
call :sub
echo %$global% %-- this is global%
echo %$local% %-- local%
echo %$return% %-- this is what called sub%
goto :eof
:sub
call @global $global
call @out $return
set $global=this is global
set $local=this is local to sub
set $return=this is what called sub |
Jason calling a label not create a local scope:
Thus I think in your last example idea, we never have working with a local scope.
With that, we can easily bypass the endlocal barrier, and we keeps working with the global heap variables prefixed with $. |
Maybe instead of scopeup name it upsc |
I don't recall ever seeing any other language that had a functionality like scopeup that returned variables to a parent scope without also returning from some routine. I am not a fan. To implement an The EXIT /B / GOTO EOF would need to be patched to look and execute any |
No surprise, as I haven't written it yet. It will only apply to heap variables, if you want local environment variables continue to use
That creates a local variable and a parent variable and I'm not going to support environment variables.
That is not an easy way to bypass the local barrier. And just because "it ought to be possible" doesn't mean it's feasible. I'll make it simple: you'll get what you're given. :) ATM that's making heap variables automatically local to calls, with functions to declare global or "out" heap variables; there will be no environment variable support. FYI, |
Mmm, I'm thinking in a new approach, create a new special type of heap variable, that will allow reassign it internally with pointer assign for save the overhead of copy it: @echo off
call :lbl
set $r= @return
:: $r= xd
goto :eof
:lbl
setlocal
set @returns=xd
endlocal
goto :eof In this case the RETURNS set the value of a heap variable that only be reassigned one time, thus outside the label, when RETURN is assigned (note: without s), it will point in this case $r to the pointer of RETURN and RETURN now points to NULL. With that we can use a heap variable for bypass the endlocal barrier, and save the overhead of recopy it. For return two values, we can wait until the support for array variables be done, thus we can reassign also two values with pointer assignment. |
I don't see how that's any different to my approach, which also allows multiple variables. @echo off
call :lbl
:: $r = xd
goto :eof
:lbl
call @out $r
set $r=xd
goto :eof Your approach does have the advantage of knowing exactly what is returned, though, without needing to refer to the subroutine. Still no support for globals (I really want heap variables automatically local). Another approach is to use a parameter, but you'd also need to refer to the subroutine to know that it requires a return argument (not really a big deal, that's what other languages do, after all). call :lbl @out $r
:: $r = xd
goto :eof
:lbl
set %1=xd
goto :eof No, that's not right, it should be with the label (or maybe even both). call :lbl $r
:: $r = xd
goto :eof
:lbl @out %1
set %1=xd
goto :eof That could be tricky to implement, and not sure I like it, anyway. |
I vote up for the |
Currently we have extensions for change directly the delayedexpansion and extensions without create a new local context, useful for some quickly switch of that options, nothing related to create local contexts.
I think will be useful have an extension for do endlocal if somene wants create a local context. but this endlocal extension will do endlocal without restore options like delayexpansions.
For write variables in the parent context a technique like this can be used:
Note: Seems that in a subroutine context goto :eof or exit /b executes and implicit endlocal only if there exists a setlocal not ended inside the subroutine.
The main issue with the previous technique is that endlocal restores delayedexpansion, causing this issue:
It prints:x=!z!
Thus I think that maybe an ENDLOCAL extension should be useful. This only end the current context, nothing more, that is the only one responsability, and are like the extensions DELAYEDEXPANSION and EXTENSIONS that also are single responsability.
The text was updated successfully, but these errors were encountered: