管理載入路徑(Manipulating the load path)

在 Octave 中當一個函數被呼叫時,Octave 會從載入路徑(load path)中尋找被呼叫的函數,此路徑預設會包含 Octave 內部存放函數的目錄與目前的工作目錄,若要查看目前的載入路徑,可以使用 path 指令:

path

這樣會列出目前所設定的載入目錄。而要增加或刪除載入路徑,可以使用 addpath()rmpath(),例如要增加一個載入路徑 "~/octave"

addpath("~/Octave")

這樣 Octave 在尋找函數時,就會連同 ~/octave 目錄一起搜尋。

addpath (dir1, ...)
addpath (dir1, ..., option)

addpath(dir1, ...) 函數可以將 dir1, ... 加入函數的載入路徑中,若 option 設為 "-begin"0,則會將此路徑加在現有的路徑之前,若設為 "-end"1,則會將此路徑加在現有的路徑之後,若省略 option 則預設為加在現有的路徑之前。所有加入的路徑必須都是存在的路徑。

genpath (dir)

genpath(dir) 函數會傳回由 dir 目錄與其所有子目錄所構成的載入路徑。

rmpath (dir1, ...)

rmpath(dir1, ...) 函數會將 dir1, ... 等目錄從目前的載入路徑中移除。

savepath (file)

savepath(file) 函數會將目前的載入路徑,扣除 Octave 初始化時所設定的路徑,儲存至檔案中,若儲存成功會傳回 0。參數 file 是指定儲存的檔名,若省略則預設為 ~/.octaverc

path (...)

path() 函數可以設定或查詢目前函數的載入路徑。若沒有指定任何參數與傳回值,則會顯示目前的載入路徑;若只有指定傳回值參數,則會傳回目前的載入路徑;若有指定傳入的參數,則會將傳入的參數以 pathsep() 連接起來變成一組載入路徑,並將目前的載入路徑設定為這組,最後傳回新的載入路徑,在建立載入路徑時,Octave 並不會檢查是否有重複的路徑。

val = pathdef ()

pathdef() 函數會傳回預設的載入路徑,若 ~/.octaverc 檔案中有包含路徑,則會將其中的路徑傳回,若 ~/.octaverc 沒有包含路徑則再檢查 <octave-home>/.../<version>/m/startup/octaverc,若有則傳回其中的路徑,若兩者都沒有任何載入路徑,則傳回 Octave 預設的載入路徑。

val = pathsep ()
old_val = pathsep (new_val)

pathsep() 函數可以設定或查詢載入路徑中分隔每個路徑所使用的分隔符號。

rehash ()

rehash() 函數可以重新初始化 Octave 載入路徑的快取(cache)。

file_in_loadpath (file)
file_in_loadpath (file, "all")

file_in_loadpath(file) 函數會在載入路徑中尋找 file 檔案,若找到此檔案則傳回其完整的絕對路徑,若找不到則傳回空陣列。若 file 指定為一個巢狀陣列,則會依序尋找巢狀陣列中的元素,傳回第一個找到的檔案,例如:

file_in_loadpath({"help.m", "plot.m"})

輸出為

ans = C:\Octave\3.2.4_gcc-4.4.0\share\octave\3.2.4\m\help\help.m

若再加入第二個參數 "all",則會將巢狀陣列中所有找到的結果傳回,若全部都找不到,則傳回空矩陣。例如:

file_in_loadpath({"help.m", "plot.m"}, "all")

輸出為

ans =

{
  [1,1] = C:\Octave\3.2.4_gcc-4.4.0\share\octave\3.2.4\m\help\help.m
  [2,1] = C:\Octave\3.2.4_gcc-4.4.0\share\octave\3.2.4\m\plot\plot.m
}
restoredefaultpath (...)

restoredefaultpath() 函數可以將函數的載入路徑重設回最原始的預設設定。

command_line_path (...)

command_line_path() 函數會傳回命令列路徑。

find_dir_in_path (dir)

find_dir_in_path(dir) 函數會在載入路徑中尋找 dir 目錄,若找到則傳回完整的絕對路徑。此函數只會尋找以 dir 結尾的目錄,假設 dir"foo/bar",則會比對到 "/some/dir/foo/bar",但不會比對到 "/some/dir/foo/bar/baz""/some/dir/allfoo/bar"

子函數(Subfunctions)

在一個函數檔案中可以定義一個以上的函數,而第二個以後的函數稱為子函數(Subfunctions)。子函數只有在同一個檔案的其他函數中可以使用,例如 f.m 檔案中的內容為:

function f ()
  printf ("in f, calling g\n");
  g ()
endfunction
function g ()
  printf ("in g, calling h\n");
  h ()
endfunction
function h ()
  printf ("in h\n")
endfunction

在此檔案中定義了一個 f() 函數與兩個子函數 g()h(),所以 g()h() 只有在 f.m 中的函數可以呼叫它們,在 f.m 檔案以外就無法使用。

私有函數(Private Functions)

在許多情況下,使用者會撰寫一些常用的函數,提供給其他的函數呼叫,當只有一個函數需要呼叫這些常用函數時,可以使用子函數的方式處理,但若是一個常用函數須要提供給多個一般函數呼叫,就無法使用子函數的方式,這個時候可以將常用函數放在一個名為 private 的目錄中,則跟 private 目錄同一層的所有函數都可以使用 private 目錄中的函數,這樣的方式稱為私有函數(Private Functions)。例如 func1() 函數會用到一個常用函數 func2()

function y = func1 (x)
  y = func2 (x);
endfunction

func1() 函數的路徑為 <directory>/func1.m,則可將 func2() 函數放置在 <directory>/private/func2.m,則所有 <directory> 中的函數都可以使用 func2() 函數,但在其他地方的函數則不能使用(因為這是私有函數)。