How to write an âoverriding wrapperâ for a function in FPATH?

Clash Royale CLAN TAG#URR8PPP
up vote
3
down vote
favorite
In the title, I use the expression "overriding wrapper" to refer to a function foo that overrides some original function falls, and calls this original function (or a copy of its) during its execution.
I have found Stack Exchange threads about this (like this one), but in my case I have the additional requirement that both the original foo as well as the overriding foo are meant to be accessible through FPATH, and autoloaded. (The overriding version presumably would appear earlier in the search sequence, thus shadowing the original version.)
Is there a way to do this?
FWIW, in the particular scenario I'm dealing with, the overriding foo just assigns some none-standard values to some global variables that the original refers to for doing its thing.
linux zsh function
add a comment |Â
up vote
3
down vote
favorite
In the title, I use the expression "overriding wrapper" to refer to a function foo that overrides some original function falls, and calls this original function (or a copy of its) during its execution.
I have found Stack Exchange threads about this (like this one), but in my case I have the additional requirement that both the original foo as well as the overriding foo are meant to be accessible through FPATH, and autoloaded. (The overriding version presumably would appear earlier in the search sequence, thus shadowing the original version.)
Is there a way to do this?
FWIW, in the particular scenario I'm dealing with, the overriding foo just assigns some none-standard values to some global variables that the original refers to for doing its thing.
linux zsh function
Are you using Debian?
â Rui F Ribeiro
Feb 1 at 21:45
@RuiFRibeiro: Both Debian and Centos
â kjo
Feb 1 at 21:52
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
In the title, I use the expression "overriding wrapper" to refer to a function foo that overrides some original function falls, and calls this original function (or a copy of its) during its execution.
I have found Stack Exchange threads about this (like this one), but in my case I have the additional requirement that both the original foo as well as the overriding foo are meant to be accessible through FPATH, and autoloaded. (The overriding version presumably would appear earlier in the search sequence, thus shadowing the original version.)
Is there a way to do this?
FWIW, in the particular scenario I'm dealing with, the overriding foo just assigns some none-standard values to some global variables that the original refers to for doing its thing.
linux zsh function
In the title, I use the expression "overriding wrapper" to refer to a function foo that overrides some original function falls, and calls this original function (or a copy of its) during its execution.
I have found Stack Exchange threads about this (like this one), but in my case I have the additional requirement that both the original foo as well as the overriding foo are meant to be accessible through FPATH, and autoloaded. (The overriding version presumably would appear earlier in the search sequence, thus shadowing the original version.)
Is there a way to do this?
FWIW, in the particular scenario I'm dealing with, the overriding foo just assigns some none-standard values to some global variables that the original refers to for doing its thing.
linux zsh function
edited Feb 11 at 13:03
Rui F Ribeiro
35.1k1269113
35.1k1269113
asked Feb 1 at 20:52
kjo
3,85373458
3,85373458
Are you using Debian?
â Rui F Ribeiro
Feb 1 at 21:45
@RuiFRibeiro: Both Debian and Centos
â kjo
Feb 1 at 21:52
add a comment |Â
Are you using Debian?
â Rui F Ribeiro
Feb 1 at 21:45
@RuiFRibeiro: Both Debian and Centos
â kjo
Feb 1 at 21:52
Are you using Debian?
â Rui F Ribeiro
Feb 1 at 21:45
Are you using Debian?
â Rui F Ribeiro
Feb 1 at 21:45
@RuiFRibeiro: Both Debian and Centos
â kjo
Feb 1 at 21:52
@RuiFRibeiro: Both Debian and Centos
â kjo
Feb 1 at 21:52
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
2
down vote
accepted
You can use this function to load the code of a function from a file in the same way that autoload does it, without the restriction that the file name has to match the function name.
## load_from FILE FUNCTION_NAME
load_from ()
eval "$2 () $(<$1) "
Here's how the wrapper code looks like. $^fpath/somefunction(N) expands to the list of definitions of somefunction in the load path ($^fpath/somefunction expands to the list of /dir/somefunction for each /dir in $fpath, and the glob qualifier (N) restricts the expansion to existing files). Note that this only works if you have a single level of wrapper and the wrapper is in the fpath.
#autoload somefunction
local some_parameter=overridden_value
local autoload_files
autoload_files=($^fpath/somefunction(N))
load_from $autoload_files[2] somefunction_wrapped
somefunction_wrapped "$@"
Thanks! Did you mean to call the functionautoload_from?
â kjo
Feb 2 at 13:55
Also, the expression$fpath/somefunction(N[2])is giving me trouble; I imaginge there's a typo in it somewhere, but I don't understand the syntax well enough to diagnose it. FWIW, if I inspect trace generated withset -x, I see that the$fpath/somefunction(N[2])is getting replaced by my entire$fpath(space-separated).
â kjo
Feb 2 at 14:32
1
@kjo My bad, I fixed some errors and added some explanations. I adapted this heavily from a function in my.zshrc(which autoloads from a directory not on$fpath, rather than from a subsequent directory on$fpathas in your case) and left a few mistakes in the adaptation.
â Gilles
Feb 2 at 21:07
add a comment |Â
up vote
3
down vote
For replacing binaries/init.d files/scripts with a wrapper in Debian, I have used in production for years, with great success, file diversions.
If you just drop by a wrapper with the same name as the original file you want to shadow, what it happens is in the next update of the corresponding package the wrapper will be most probably rewritten by the file you intend to replace.
So for instance, for adding a wrapper for gcc, you would do:
sudo dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc
After that, you can place your wrapper at /usr/bin/gcc.
From then on, the old gcc binary will be /usr/bin/gcc.real, and most importantly, all the subsequent gcc future updates done/installed by Debian APT system, will install new instances of /usr/bin/gcc as /usr/bin/gcc.real and will leave your wrapper undisturbed.
See Replacing binaries with dpkg-divert
From man dpkg-divert
dpkg-divert is the utility used to set up and update the list of
diversions.
File diversions are a way of forcing dpkg(1) not to install a file
into its location, but to a diverted location. Diversions can be used
through the Debian package scripts to move a file away when it causes
a conflict. System administrators can also use it to override some
package's configuration file, or whenever some files (which aren't
marked as âÂÂconffilesâÂÂ) need to be preserved by dpkg, when installing a
newer version of a package which contains those files.
PS I used this technique for adding extra options to the BIND and ISC-DHCP init scripts.
I'm looking for something that does not depend on the distro, but, nonetheless,dpkg-divertdoes look like a very useful tool. Thanks!
â kjo
Feb 2 at 22:08
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
You can use this function to load the code of a function from a file in the same way that autoload does it, without the restriction that the file name has to match the function name.
## load_from FILE FUNCTION_NAME
load_from ()
eval "$2 () $(<$1) "
Here's how the wrapper code looks like. $^fpath/somefunction(N) expands to the list of definitions of somefunction in the load path ($^fpath/somefunction expands to the list of /dir/somefunction for each /dir in $fpath, and the glob qualifier (N) restricts the expansion to existing files). Note that this only works if you have a single level of wrapper and the wrapper is in the fpath.
#autoload somefunction
local some_parameter=overridden_value
local autoload_files
autoload_files=($^fpath/somefunction(N))
load_from $autoload_files[2] somefunction_wrapped
somefunction_wrapped "$@"
Thanks! Did you mean to call the functionautoload_from?
â kjo
Feb 2 at 13:55
Also, the expression$fpath/somefunction(N[2])is giving me trouble; I imaginge there's a typo in it somewhere, but I don't understand the syntax well enough to diagnose it. FWIW, if I inspect trace generated withset -x, I see that the$fpath/somefunction(N[2])is getting replaced by my entire$fpath(space-separated).
â kjo
Feb 2 at 14:32
1
@kjo My bad, I fixed some errors and added some explanations. I adapted this heavily from a function in my.zshrc(which autoloads from a directory not on$fpath, rather than from a subsequent directory on$fpathas in your case) and left a few mistakes in the adaptation.
â Gilles
Feb 2 at 21:07
add a comment |Â
up vote
2
down vote
accepted
You can use this function to load the code of a function from a file in the same way that autoload does it, without the restriction that the file name has to match the function name.
## load_from FILE FUNCTION_NAME
load_from ()
eval "$2 () $(<$1) "
Here's how the wrapper code looks like. $^fpath/somefunction(N) expands to the list of definitions of somefunction in the load path ($^fpath/somefunction expands to the list of /dir/somefunction for each /dir in $fpath, and the glob qualifier (N) restricts the expansion to existing files). Note that this only works if you have a single level of wrapper and the wrapper is in the fpath.
#autoload somefunction
local some_parameter=overridden_value
local autoload_files
autoload_files=($^fpath/somefunction(N))
load_from $autoload_files[2] somefunction_wrapped
somefunction_wrapped "$@"
Thanks! Did you mean to call the functionautoload_from?
â kjo
Feb 2 at 13:55
Also, the expression$fpath/somefunction(N[2])is giving me trouble; I imaginge there's a typo in it somewhere, but I don't understand the syntax well enough to diagnose it. FWIW, if I inspect trace generated withset -x, I see that the$fpath/somefunction(N[2])is getting replaced by my entire$fpath(space-separated).
â kjo
Feb 2 at 14:32
1
@kjo My bad, I fixed some errors and added some explanations. I adapted this heavily from a function in my.zshrc(which autoloads from a directory not on$fpath, rather than from a subsequent directory on$fpathas in your case) and left a few mistakes in the adaptation.
â Gilles
Feb 2 at 21:07
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
You can use this function to load the code of a function from a file in the same way that autoload does it, without the restriction that the file name has to match the function name.
## load_from FILE FUNCTION_NAME
load_from ()
eval "$2 () $(<$1) "
Here's how the wrapper code looks like. $^fpath/somefunction(N) expands to the list of definitions of somefunction in the load path ($^fpath/somefunction expands to the list of /dir/somefunction for each /dir in $fpath, and the glob qualifier (N) restricts the expansion to existing files). Note that this only works if you have a single level of wrapper and the wrapper is in the fpath.
#autoload somefunction
local some_parameter=overridden_value
local autoload_files
autoload_files=($^fpath/somefunction(N))
load_from $autoload_files[2] somefunction_wrapped
somefunction_wrapped "$@"
You can use this function to load the code of a function from a file in the same way that autoload does it, without the restriction that the file name has to match the function name.
## load_from FILE FUNCTION_NAME
load_from ()
eval "$2 () $(<$1) "
Here's how the wrapper code looks like. $^fpath/somefunction(N) expands to the list of definitions of somefunction in the load path ($^fpath/somefunction expands to the list of /dir/somefunction for each /dir in $fpath, and the glob qualifier (N) restricts the expansion to existing files). Note that this only works if you have a single level of wrapper and the wrapper is in the fpath.
#autoload somefunction
local some_parameter=overridden_value
local autoload_files
autoload_files=($^fpath/somefunction(N))
load_from $autoload_files[2] somefunction_wrapped
somefunction_wrapped "$@"
edited Feb 2 at 22:05
kjo
3,85373458
3,85373458
answered Feb 2 at 0:15
Gilles
506k11910001528
506k11910001528
Thanks! Did you mean to call the functionautoload_from?
â kjo
Feb 2 at 13:55
Also, the expression$fpath/somefunction(N[2])is giving me trouble; I imaginge there's a typo in it somewhere, but I don't understand the syntax well enough to diagnose it. FWIW, if I inspect trace generated withset -x, I see that the$fpath/somefunction(N[2])is getting replaced by my entire$fpath(space-separated).
â kjo
Feb 2 at 14:32
1
@kjo My bad, I fixed some errors and added some explanations. I adapted this heavily from a function in my.zshrc(which autoloads from a directory not on$fpath, rather than from a subsequent directory on$fpathas in your case) and left a few mistakes in the adaptation.
â Gilles
Feb 2 at 21:07
add a comment |Â
Thanks! Did you mean to call the functionautoload_from?
â kjo
Feb 2 at 13:55
Also, the expression$fpath/somefunction(N[2])is giving me trouble; I imaginge there's a typo in it somewhere, but I don't understand the syntax well enough to diagnose it. FWIW, if I inspect trace generated withset -x, I see that the$fpath/somefunction(N[2])is getting replaced by my entire$fpath(space-separated).
â kjo
Feb 2 at 14:32
1
@kjo My bad, I fixed some errors and added some explanations. I adapted this heavily from a function in my.zshrc(which autoloads from a directory not on$fpath, rather than from a subsequent directory on$fpathas in your case) and left a few mistakes in the adaptation.
â Gilles
Feb 2 at 21:07
Thanks! Did you mean to call the function
autoload_from?â kjo
Feb 2 at 13:55
Thanks! Did you mean to call the function
autoload_from?â kjo
Feb 2 at 13:55
Also, the expression
$fpath/somefunction(N[2]) is giving me trouble; I imaginge there's a typo in it somewhere, but I don't understand the syntax well enough to diagnose it. FWIW, if I inspect trace generated with set -x, I see that the $fpath/somefunction(N[2]) is getting replaced by my entire $fpath (space-separated).â kjo
Feb 2 at 14:32
Also, the expression
$fpath/somefunction(N[2]) is giving me trouble; I imaginge there's a typo in it somewhere, but I don't understand the syntax well enough to diagnose it. FWIW, if I inspect trace generated with set -x, I see that the $fpath/somefunction(N[2]) is getting replaced by my entire $fpath (space-separated).â kjo
Feb 2 at 14:32
1
1
@kjo My bad, I fixed some errors and added some explanations. I adapted this heavily from a function in my
.zshrc (which autoloads from a directory not on $fpath, rather than from a subsequent directory on $fpath as in your case) and left a few mistakes in the adaptation.â Gilles
Feb 2 at 21:07
@kjo My bad, I fixed some errors and added some explanations. I adapted this heavily from a function in my
.zshrc (which autoloads from a directory not on $fpath, rather than from a subsequent directory on $fpath as in your case) and left a few mistakes in the adaptation.â Gilles
Feb 2 at 21:07
add a comment |Â
up vote
3
down vote
For replacing binaries/init.d files/scripts with a wrapper in Debian, I have used in production for years, with great success, file diversions.
If you just drop by a wrapper with the same name as the original file you want to shadow, what it happens is in the next update of the corresponding package the wrapper will be most probably rewritten by the file you intend to replace.
So for instance, for adding a wrapper for gcc, you would do:
sudo dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc
After that, you can place your wrapper at /usr/bin/gcc.
From then on, the old gcc binary will be /usr/bin/gcc.real, and most importantly, all the subsequent gcc future updates done/installed by Debian APT system, will install new instances of /usr/bin/gcc as /usr/bin/gcc.real and will leave your wrapper undisturbed.
See Replacing binaries with dpkg-divert
From man dpkg-divert
dpkg-divert is the utility used to set up and update the list of
diversions.
File diversions are a way of forcing dpkg(1) not to install a file
into its location, but to a diverted location. Diversions can be used
through the Debian package scripts to move a file away when it causes
a conflict. System administrators can also use it to override some
package's configuration file, or whenever some files (which aren't
marked as âÂÂconffilesâÂÂ) need to be preserved by dpkg, when installing a
newer version of a package which contains those files.
PS I used this technique for adding extra options to the BIND and ISC-DHCP init scripts.
I'm looking for something that does not depend on the distro, but, nonetheless,dpkg-divertdoes look like a very useful tool. Thanks!
â kjo
Feb 2 at 22:08
add a comment |Â
up vote
3
down vote
For replacing binaries/init.d files/scripts with a wrapper in Debian, I have used in production for years, with great success, file diversions.
If you just drop by a wrapper with the same name as the original file you want to shadow, what it happens is in the next update of the corresponding package the wrapper will be most probably rewritten by the file you intend to replace.
So for instance, for adding a wrapper for gcc, you would do:
sudo dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc
After that, you can place your wrapper at /usr/bin/gcc.
From then on, the old gcc binary will be /usr/bin/gcc.real, and most importantly, all the subsequent gcc future updates done/installed by Debian APT system, will install new instances of /usr/bin/gcc as /usr/bin/gcc.real and will leave your wrapper undisturbed.
See Replacing binaries with dpkg-divert
From man dpkg-divert
dpkg-divert is the utility used to set up and update the list of
diversions.
File diversions are a way of forcing dpkg(1) not to install a file
into its location, but to a diverted location. Diversions can be used
through the Debian package scripts to move a file away when it causes
a conflict. System administrators can also use it to override some
package's configuration file, or whenever some files (which aren't
marked as âÂÂconffilesâÂÂ) need to be preserved by dpkg, when installing a
newer version of a package which contains those files.
PS I used this technique for adding extra options to the BIND and ISC-DHCP init scripts.
I'm looking for something that does not depend on the distro, but, nonetheless,dpkg-divertdoes look like a very useful tool. Thanks!
â kjo
Feb 2 at 22:08
add a comment |Â
up vote
3
down vote
up vote
3
down vote
For replacing binaries/init.d files/scripts with a wrapper in Debian, I have used in production for years, with great success, file diversions.
If you just drop by a wrapper with the same name as the original file you want to shadow, what it happens is in the next update of the corresponding package the wrapper will be most probably rewritten by the file you intend to replace.
So for instance, for adding a wrapper for gcc, you would do:
sudo dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc
After that, you can place your wrapper at /usr/bin/gcc.
From then on, the old gcc binary will be /usr/bin/gcc.real, and most importantly, all the subsequent gcc future updates done/installed by Debian APT system, will install new instances of /usr/bin/gcc as /usr/bin/gcc.real and will leave your wrapper undisturbed.
See Replacing binaries with dpkg-divert
From man dpkg-divert
dpkg-divert is the utility used to set up and update the list of
diversions.
File diversions are a way of forcing dpkg(1) not to install a file
into its location, but to a diverted location. Diversions can be used
through the Debian package scripts to move a file away when it causes
a conflict. System administrators can also use it to override some
package's configuration file, or whenever some files (which aren't
marked as âÂÂconffilesâÂÂ) need to be preserved by dpkg, when installing a
newer version of a package which contains those files.
PS I used this technique for adding extra options to the BIND and ISC-DHCP init scripts.
For replacing binaries/init.d files/scripts with a wrapper in Debian, I have used in production for years, with great success, file diversions.
If you just drop by a wrapper with the same name as the original file you want to shadow, what it happens is in the next update of the corresponding package the wrapper will be most probably rewritten by the file you intend to replace.
So for instance, for adding a wrapper for gcc, you would do:
sudo dpkg-divert --add --rename --divert /usr/bin/gcc.real /usr/bin/gcc
After that, you can place your wrapper at /usr/bin/gcc.
From then on, the old gcc binary will be /usr/bin/gcc.real, and most importantly, all the subsequent gcc future updates done/installed by Debian APT system, will install new instances of /usr/bin/gcc as /usr/bin/gcc.real and will leave your wrapper undisturbed.
See Replacing binaries with dpkg-divert
From man dpkg-divert
dpkg-divert is the utility used to set up and update the list of
diversions.
File diversions are a way of forcing dpkg(1) not to install a file
into its location, but to a diverted location. Diversions can be used
through the Debian package scripts to move a file away when it causes
a conflict. System administrators can also use it to override some
package's configuration file, or whenever some files (which aren't
marked as âÂÂconffilesâÂÂ) need to be preserved by dpkg, when installing a
newer version of a package which contains those files.
PS I used this technique for adding extra options to the BIND and ISC-DHCP init scripts.
edited Feb 2 at 23:13
answered Feb 1 at 22:47
Rui F Ribeiro
35.1k1269113
35.1k1269113
I'm looking for something that does not depend on the distro, but, nonetheless,dpkg-divertdoes look like a very useful tool. Thanks!
â kjo
Feb 2 at 22:08
add a comment |Â
I'm looking for something that does not depend on the distro, but, nonetheless,dpkg-divertdoes look like a very useful tool. Thanks!
â kjo
Feb 2 at 22:08
I'm looking for something that does not depend on the distro, but, nonetheless,
dpkg-divert does look like a very useful tool. Thanks!â kjo
Feb 2 at 22:08
I'm looking for something that does not depend on the distro, but, nonetheless,
dpkg-divert does look like a very useful tool. Thanks!â kjo
Feb 2 at 22:08
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f421291%2fhow-to-write-an-overriding-wrapper-for-a-function-in-fpath%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Are you using Debian?
â Rui F Ribeiro
Feb 1 at 21:45
@RuiFRibeiro: Both Debian and Centos
â kjo
Feb 1 at 21:52