dispatch()
函數可以建立函數的別名(alias),它可以將一個函數所有的呼叫都重新導向至另一個函數,或是只針對一些特定的變數類型,例如:
function y = spsin (x) printf ("Calling spsin\n"); fflush(stdout); y = spfun ("sin", x); endfunction
spsin()
是一個自行定義的函數,接著建立函數別名:
dispatch ("sin", "spsin", "sparse matrix");
這樣會將會將函數 spsin()
建立一個別名為 sin()
,但此別名只有針對 sparse matrix 的變數類型,
y0 = sin(eye(3))
因為 eye(3)
不是 sparse matrix,所以會使用原本內建的 sin()
函數,輸出為
y0 = 0.84147 0.00000 0.00000 0.00000 0.84147 0.00000 0.00000 0.00000 0.84147
y1 = sin(speye(3))
這裡的 speye(3)
是一個 sparse matrix,所以會呼叫 spsin()
函數,輸出為
Calling spsin y1 = Compressed Column Sparse (rows = 3, cols = 3, nnz = 3 [33%]) (1, 1) -> 0.84147 (2, 2) -> 0.84147 (3, 3) -> 0.84147
內建的 sin()
函數其實本來就可以處理 sparse matrix,這裡只是為了示範別名的用法才如此使用。
dispatch (f, r, type)
dispatch(f, r, type)
函數會建立一個 r()
函數的別名,使 f()
函數在傳入的第一個參數為 type
類型時,以 r()
函數取代。若將 type
設為 "any"
,則當沒有其他的類型的別名時,都會呼叫 r()
。建立別名之後,原始的 f()
函數可以使用 builtin(f, ...)
函數來呼叫。
若呼叫 dispatch()
函數而省略 r
參數,則會將作用於 f()
函數 type
類型的別名移除;若省略 r
與 type
兩個參數,則會顯示 f()
函數所有的別名。
[...] builtin (f, ...)
builtin(f, ...)
函數會忽略別名呼叫原始的 f()
函數。
透過別名可以將一個函數連結至許多個函數,若是使用者在命令列中輸入一個函數的別名,而此別名所指向的函數事實上是儲存在另外一的檔案中,此時 Octave 若以函數的名稱去搜尋檔案,就會發生找不到函數檔案的問題,最簡單的解決方法就是將此函數的定義檔複製一份,並以別名的名稱命名,但是這樣又會浪費硬碟空間。比較好的做法是使用 autoload()
函數設定函數的儲存位置。
autoload (function, file)
autoload(function, file)
函數會設定函數 function
的儲存位置為 file
檔案,當 Octave 要載入 function
函數時,就會從 file
檔案中載入。
file
參數應為一個絕對路徑,若設為不含路徑的檔名,則此檔案必須與 autoload()
函數所在的檔案有相同的路徑,此檔案不可依靠載入路徑來載入。
一般來說在 autoload()
函數會用在 ADD_PKG
這個特殊的指令稿中,在載入路徑的目錄中若包含此指令稿,則在此路徑加入目前的載入路徑時,就會自動執行 ADD_PKG
,這個指令稿中可以設定這個目錄中函數的載入方式:
autoload ("foo", "bar.oct");
這會設定 foo()
函數所載入的檔案為 bar.oct
。
若呼叫 autoload()
函數沒有加任何參數,則會顯示目前所有函數的載入設定表。
mlock()
可以將函數鎖定在記憶體中,不要被 clear()
函數移除,這個常會用在 oct
檔或 mex
檔中包含初始化的函數,讓 clear()
函數不要刪除已經初始化的內容。例如:
function count_calls () mlock (); persistent calls = 0; printf ("'count_calls' has been called %d times\n", ++calls); endfunction
這樣會鎖定 count_calls()
函數,使其不會被 clear()
函數刪除:
count_calls ();
輸出為
'count_calls' has been called 1 times
clear count_calls; count_calls ();
輸出為
'count_calls' has been called 2 times
要查詢函數是否有被鎖定,可用 mislocked()
函數:
mislocked ("count_calls")
而要解除鎖定可以使用 munlock()
函數:
munlock ("count_calls");
mlock ()
mlock()
函數會將目前的函數鎖定,讓此函數不會被 clear()
函數刪除。
munlock (fcn)
munlock(fcn)
函數會將 fcn
函數解除鎖定,若不指定 fcn
參數,則會將目前的函數解除鎖定。
mislocked (fcn)
mislocked(fcn)
函數可以判斷 fcn
函數是否被鎖定,若不指定 fcn
參數,則會判斷目前的函數是否被鎖定。
在 Octave 中有許多種定義函數的方式,當同一個函數名稱有多種定義方式時,就會依照函數優先權(Function Precedence)來決定使用哪一個,以下是 Octave 的所使用的優先權列表:
autoload()
所設定的函數,請參考函數別名與載入設定。.oct
檔、 .mex
檔、 .m
檔。numel()
與 size()
等。