Hi,
I stumlede upon a surprising problem: how do I source I file in a path
relative to where the file is placed, rather than relative to where
the file is sourced _from_.
If I have file A which sources file B which in turn wants to source
file C, all my file commads within file B seems to be relative to
where file A is sourced, i.e. the pwd of the interpreter. I think
[info script] does the same. So, how can I find out the file name of
B?
/Fredrik
|
|
0
|
|
|
|
Reply
|
Fredrik
|
9/27/2010 7:30:32 AM |
|
On Sep 27, 9:30=A0am, Fredrik Karlsson <dargo...@gmail.com> wrote:
> Hi,
>
> I stumlede upon a surprising problem: how do I source I file in a path
> relative to where the file is placed, rather than relative to where
> the file is sourced _from_.
>
> If I have file A which sources file B which in turn wants to source
> file C, all my file commads within file B seems to be relative to
> where file A is sourced, i.e. the pwd of the interpreter. I think
> [info script] does the same. So, how can I find out the file name of
> B?
Assuming you're not [cd]ing within Tcl[*], the [info script] of each
sourced file is the path that was used to reach it (including the main
script passed as argument to tclsh), so it is valid relatively to the
process' cwd. (Note that this path may be absolute or relative
depending on the way you issued the command: absolute if /typed/
explicitly or searched in $PATH, relative if ./typed/this/way).
In all cases, this means that [file dirname [info script]] is
faithful, and can be used to reach neighboring paths.
-Alex
[*] Avoid [cd] except in interactive tclsh. You'll fare better.
|
|
0
|
|
|
|
Reply
|
Alexandre
|
9/27/2010 8:12:46 AM
|
|
On 27 sep, 10:12, Alexandre Ferrieux <alexandre.ferri...@gmail.com>
wrote:
> On Sep 27, 9:30=A0am, Fredrik Karlsson <dargo...@gmail.com> wrote:
>
> > Hi,
>
> > I stumlede upon a surprising problem: how do I source I file in a path
> > relative to where the file is placed, rather than relative to where
> > the file is sourced _from_.
>
> > If I have file A which sources file B which in turn wants to source
> > file C, all my file commads within file B seems to be relative to
> > where file A is sourced, i.e. the pwd of the interpreter. I think
> > [info script] does the same. So, how can I find out the file name of
> > B?
>
> Assuming you're not [cd]ing within Tcl[*], the [info script] of each
> sourced file is the path that was used to reach it (including the main
> script passed as argument to tclsh), so it is valid relatively to the
> process' cwd. (Note that this path may be absolute or relative
> depending on the way you issued the command: absolute if /typed/
> explicitly or searched in $PATH, relative if ./typed/this/way).
>
> In all cases, this means that [file dirname [info script]] is
> faithful, and can be used to reach neighboring paths.
>
> -Alex
>
> [*] Avoid [cd] except in interactive tclsh. You'll fare better.
One caveat: [info script] is faithful, as Alex calls it, only during
the [source]'ing of the file - so, not inside a procedure if that
is run later. So if you source the following file, you ought to
get the right output. If you run the procedure later, you won't:
# Example of [info script]
proc printScript {} {
puts "Sourcing: [info script]"
}
printScript ;# Invoked during the source command for this file!
# End of file
Regards,
Arjen
|
|
0
|
|
|
|
Reply
|
arjen.markus895 (633)
|
9/27/2010 8:38:58 AM
|
|
On Sep 27, 10:38=A0am, Arjen Markus <arjen.markus...@gmail.com> wrote:
> On 27 sep, 10:12, Alexandre Ferrieux <alexandre.ferri...@gmail.com>
> wrote:
>
>
>
>
>
> > On Sep 27, 9:30=A0am, Fredrik Karlsson <dargo...@gmail.com> wrote:
>
> > > Hi,
>
> > > I stumlede upon a surprising problem: how do I source I file in a pat=
h
> > > relative to where the file is placed, rather than relative to where
> > > the file is sourced _from_.
>
> > > If I have file A which sources file B which in turn wants to source
> > > file C, all my file commads within file B seems to be relative to
> > > where file A is sourced, i.e. the pwd of the interpreter. I think
> > > [info script] does the same. So, how can I find out the file name of
> > > B?
>
> > Assuming you're not [cd]ing within Tcl[*], the [info script] of each
> > sourced file is the path that was used to reach it (including the main
> > script passed as argument to tclsh), so it is valid relatively to the
> > process' cwd. (Note that this path may be absolute or relative
> > depending on the way you issued the command: absolute if /typed/
> > explicitly or searched in $PATH, relative if ./typed/this/way).
>
> > In all cases, this means that [file dirname [info script]] is
> > faithful, and can be used to reach neighboring paths.
>
> > -Alex
>
> > [*] Avoid [cd] except in interactive tclsh. You'll fare better.
>
> One caveat: [info script] is faithful, as Alex calls it, only during
> the [source]'ing of the file - so, not inside a procedure if that
> is run later. So if you source the following file, you ought to
> get the right output. If you run the procedure later, you won't:
>
> # Example of [info script]
> proc printScript {} {
> =A0 =A0 puts "Sourcing: [info script]"}
>
> printScript ;# Invoked during the source command for this file!
> # End of file
>
> Regards,
>
> Arjen
To get around this "problem" (it isn't once you know) most of my
libraries have a libdir variable, declared and initialised at source
time, which can later be accessed by the procedures of the libraries
if necessary (all this within namespaces). Pseudo-code below:
namespace eval ::finefinenamespace {
variable NSVAR
if {![info exists NSVAR]} {
array set NSVAR {
an_opt "its value"
}
variable libdir [file dirname [file normalize [info script]]]
}
}
proc ::finefinenamespace::one_proc {} {
variable NSVAR
variable libdir
# Do something with $libdir
}
|
|
0
|
|
|
|
Reply
|
Emmanuel
|
9/28/2010 7:51:44 AM
|
|
On Sep 28, 9:51=A0am, Emmanuel Frecon <efre...@gmail.com> wrote:
> On Sep 27, 10:38=A0am, Arjen Markus <arjen.markus...@gmail.com> wrote:
>
>
>
>
>
> > On 27 sep, 10:12, Alexandre Ferrieux <alexandre.ferri...@gmail.com>
> > wrote:
>
> > > On Sep 27, 9:30=A0am, Fredrik Karlsson <dargo...@gmail.com> wrote:
>
> > > > Hi,
>
> > > > I stumlede upon a surprising problem: how do I source I file in a p=
ath
> > > > relative to where the file is placed, rather than relative to where
> > > > the file is sourced _from_.
>
> > > > If I have file A which sources file B which in turn wants to source
> > > > file C, all my file commads within file B seems to be relative to
> > > > where file A is sourced, i.e. the pwd of the interpreter. I think
> > > > [info script] does the same. So, how can I find out the file name o=
f
> > > > B?
>
> > > Assuming you're not [cd]ing within Tcl[*], the [info script] of each
> > > sourced file is the path that was used to reach it (including the mai=
n
> > > script passed as argument to tclsh), so it is valid relatively to the
> > > process' cwd. (Note that this path may be absolute or relative
> > > depending on the way you issued the command: absolute if /typed/
> > > explicitly or searched in $PATH, relative if ./typed/this/way).
>
> > > In all cases, this means that [file dirname [info script]] is
> > > faithful, and can be used to reach neighboring paths.
>
> > > -Alex
>
> > > [*] Avoid [cd] except in interactive tclsh. You'll fare better.
>
> > One caveat: [info script] is faithful, as Alex calls it, only during
> > the [source]'ing of the file - so, not inside a procedure if that
> > is run later. So if you source the following file, you ought to
> > get the right output. If you run the procedure later, you won't:
>
> > # Example of [info script]
> > proc printScript {} {
> > =A0 =A0 puts "Sourcing: [info script]"}
>
> > printScript ;# Invoked during the source command for this file!
> > # End of file
>
> > Regards,
>
> > Arjen
>
> To get around this "problem" (it isn't once you know) most of my
> libraries have a libdir variable, declared and initialised at source
> time, which can later be accessed by the procedures of the libraries
> if necessary (all this within namespaces). Pseudo-code below:
>
> namespace eval ::finefinenamespace {
> =A0 =A0 variable NSVAR
> =A0 =A0 if {![info exists NSVAR]} {
> =A0 =A0 =A0 =A0 array set NSVAR {
> =A0 =A0 =A0 =A0 =A0 =A0 an_opt =A0 =A0"its value"
> =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 variable libdir [file dirname [file normalize [info scrip=
t]]]
> =A0 =A0 }
>
> }
>
> proc ::finefinenamespace::one_proc {} {
> =A0 =A0 variable NSVAR
> =A0 =A0 variable libdir
>
> =A0 =A0 # Do something with $libdir
>
>
>
> }
I use something like the following near the top of most of my
applications:
set here [file dirname [file normalize [info script]]]
source [file join $here foo.tcl]
That way $::here is available later as the root of the application
source dir, fully qualified so not affected by later [cd]'s
Works whether run directly, or inside a starkit or similar (where
[pwd] and [file dirname [info script]] are completely different even
if run like ./foo_application). The only place I've found where it
doesn't work is a long time ago in the pre-vfs days using things like
TclWrap (iirc), where [info script] gave a blank string and I had to
fall back to [info nameofexecutable]
Cyan
|
|
0
|
|
|
|
Reply
|
cyan.ogilvie (32)
|
9/28/2010 12:46:55 PM
|
|
On Sep 27, 12:30=A0am, Fredrik Karlsson <dargo...@gmail.com> wrote:
> Hi,
>
> I stumlede upon a surprising problem: how do I source I file in a path
> relative to where the file is placed, rather than relative to where
> the file is sourced _from_.
>
> If I have file A which sources file B which in turn wants to source
> file C, all my file commads within file B seems to be relative to
> where file A is sourced, i.e. the pwd of the interpreter. I think
> [info script] does the same. So, how can I find out the file name of
> B?
>
> /Fredrik
The problem you describe is exactly why tcl has commands like
pkg_mkIndex that help you organizes your code. The source command is
really only good for single file applications. If your application has
more than one file, then organize you files using pkg_mkIndex and
extent that auto_path variable.
tomk
|
|
0
|
|
|
|
Reply
|
tomk
|
9/28/2010 4:57:02 PM
|
|
On Sep 27, 1:38=A0am, Arjen Markus <arjen.markus...@gmail.com> wrote:
> On 27 sep, 10:12, Alexandre Ferrieux <alexandre.ferri...@gmail.com>
> wrote:
>
>
>
>
>
> > On Sep 27, 9:30=A0am, Fredrik Karlsson <dargo...@gmail.com> wrote:
>
> > > Hi,
>
> > > I stumlede upon a surprising problem: how do I source I file in a pat=
h
> > > relative to where the file is placed, rather than relative to where
> > > the file is sourced _from_.
>
> > > If I have file A which sources file B which in turn wants to source
> > > file C, all my file commads within file B seems to be relative to
> > > where file A is sourced, i.e. the pwd of the interpreter. I think
> > > [info script] does the same. So, how can I find out the file name of
> > > B?
>
> > Assuming you're not [cd]ing within Tcl[*], the [info script] of each
> > sourced file is the path that was used to reach it (including the main
> > script passed as argument to tclsh), so it is valid relatively to the
> > process' cwd. (Note that this path may be absolute or relative
> > depending on the way you issued the command: absolute if /typed/
> > explicitly or searched in $PATH, relative if ./typed/this/way).
>
> > In all cases, this means that [file dirname [info script]] is
> > faithful, and can be used to reach neighboring paths.
>
> > -Alex
>
> > [*] Avoid [cd] except in interactive tclsh. You'll fare better.
>
> One caveat: [info script] is faithful, as Alex calls it, only during
> the [source]'ing of the file - so, not inside a procedure if that
> is run later. So if you source the following file, you ought to
> get the right output. If you run the procedure later, you won't:
>
> # Example of [info script]
> proc printScript {} {
> =A0 =A0 puts "Sourcing: [info script]"}
>
> printScript ;# Invoked during the source command for this file!
> # End of file
>
There are three/four cases for [info script]:
1. directly in interactive shell, returns empty string
% info script
1a. called in a script:
#! tclsh
info script
% source myfile.tcl
myfile.tcl
2. proc which calls [info script]:
2a. called from interactive shell (returns empty string):
% proc where {} {puts [info script]}
% where
2b. called from a script:
#! tclsh
where
% source where.tcl
where.tcl
3. proc which calls [info script] called from another proc:
#! tclsh
proc where2 {} {where}
where2
% source where2.tcl
%
In summary:
A. interactive shell isn't a script [info script] =3D=3D> ""
B. script level procs are in a script [info script] =3D=3D> script where
proc was executed
C. procs in another proc are not in a script [info script] =3D=3D> ""
So if you intend to get consistent behavior from a procedure, don't
use [info script], store the info in a variable set at script level,
or pass in the info directly to the procedure.
Now back to the original question:
If I have file A which sources file B which in turn wants to source
file C, all my file commads within file B seems to be relative to
where file A is sourced, i.e. the pwd of the interpreter. I think
[info script] does the same. So, how can I find out the file name of
B?
file A knows about file B, but should not need to know about file C.
If you think of a script as an object, you decouple file C from file
A.
Given this, I like to explicitly use normalized absolute paths which
are computed using local information only.
One example of a script file:
# Replacement procs for nsd
# Use this with nstclsh
namespace eval ::ns {
variable version 0.9
}
::tnt::sourceFile [file normalize [file join [file dirname [info
script]] "ns-conn-procs.tcl"]]
::tnt::sourceFile [file normalize [file join [file dirname [info
script]] "nsd-local-conf.tcl"]]
if {$::ns::load_commands} {
::tnt::log::log Notice "Loading ns replacement procs"
::tnt::sourceFile [file normalize [file join [file dirname [info
script]] "ns-set-procs.tcl"]]
::tnt::sourceFile [file normalize [file join [file dirname [info
script]] "ns-mime-procs.tcl"]]
::tnt::sourceFile [file normalize [file join [file dirname [info
script]] "replacement-procs.tcl"]]
}
Here ::tnt::sourceFile is an example of passing in path data to the
procedure.
The above file is sourced from a procedure, instead of from file A.
|
|
0
|
|
|
|
Reply
|
tom.rmadilo (754)
|
9/28/2010 8:47:06 PM
|
|
|
6 Replies
512 Views
(page loaded in 1.225 seconds)
Similiar Articles: Current file - comp.lang.tclHi, I stumlede upon a surprising problem: how do I source I file in a path relative to where the file is placed, rather than relative to where th... How to remove all subdirectory/file under current directory ...Hi All Any suggestion ? Currently, I am using below shell command cd delete_path rm -f * # remove current directory files rm -f */* # ... Your current security setting do not allow this file to be ...http://support.microsoft.com/kb/281679/en-us?spid=2073&sid=global 1. Quit all programs that are running. 2. Click Start, and then click Run. 3. T... set path to latest file, when starting - comp.soft-sys.matlab ...Hi Is it able to automatically set the current folder and path to those of the latest closed m file, when starting matlab? Mine is always in Des... file copy: invalid argument - comp.lang.tclHi, I am using file copy as follows: if {[catch {file copy -- $fileToCopy $destDir/[format "%06d" $current]-[file tail $fileToCopy]} msg]} { ... Current controlled current source output - comp.soft-sys.matlab ...Current file - comp.lang.tcl So if you source the following file, you ought to > get the right output. ... This tip explains how the current working directory can be ... lockf() question - comp.unix.solarisSo I don't think there should be any performance implication due to the current location in the file. -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE ... Reading an unformatted file - comp.lang.fortranUse a binary viewing tool such as "od" to see and understand your current file structure. 2. Make a short test program to write out a dummy file that is supposed to ... Acrobat printing default current page - comp.text.pdfHello, i have the acrobat 5 and a very very long pdf-file. I want to set the default printing properties to current page. How can i realize this? Th... use File Descriptor in the projet with projmod - comp.unix.solaris ...Current file - comp.lang.tcl use File Descriptor in the projet with projmod - comp.unix.solaris ... Current file - comp.lang.tcl To get the current position in a file ... current file definition | English definition dictionary | Reverso ...Reverso offers you access to an English definition and synonym dictionary for current file and thousands of other words. You can complete the definition of current ... Current File Versions - Microsoft Corporation: Software ...Updating your local copies of files to versions from the master source code control files is called getting or synchronizing files. In any software project ... 7/29/2012 8:55:51 AM
|