2015-03-17 8 views
8

Sono a conoscenza della funzionalità delle tabelle deboli in Lua, tuttavia mi piacerebbe avere un riferimento debole con una singola variabile.Riferimento debole Lua

Ho visto this proposal che suggerisce un API come segue:

-- creation 
ref = weakref(obj) 
-- dereference 
obj = ref() 

che sembrerebbe l'ideale. Tuttavia questo non sembra essere nella documentazione altrove; solo tavoli deboli.

Esiste qualcosa di analogo alla funzionalità weak reference to object di Python?

+1

Che cosa stai cercando di fare qui alla fine? Puoi emularlo tu stesso usando una tabella con metatable credo (o con 'newproxy' e una metatable) se davvero ne hai bisogno. –

+0

Sto usando la classe media per OO, passando una chiusura da objA a objB. Quando objA esce dal campo di applicazione, la chiusura impedisce a entrambe le istanze di essere convertite in GC perché contiene un riferimento a objA. Mai sentito parlare di newproxy prima, andare su google ... – MarkNS

+0

hmmm .. "La funzione newproxy non documentata è stata rimossa in Lua 5.2, poiché è stata ridondata da altre funzionalità aggiunte in quella versione" da http: // lua-users .org/wiki/HiddenFeatures – MarkNS

risposta

4

Qualcosa di simile si può fare quello che vuoi io credo:

local obj = {value = "obj.value"} 

local ref = setmetatable({real = obj}, {__mode = "v", __call = function(self) return self.real end}) 

print(obj.value) 
print(ref.real.value) 
print(ref().value) 

obj = nil 
collectgarbage() 
collectgarbage() 

print(obj) 
print(ref.real) 
print(ref()) 

La parte __call è opzionale ma ti dà la sintassi della chiamata ref(). Senza di esso è necessario utilizzare la versione di accesso diretto.

7

Quando lua non fornisce qualcosa, c'è spesso un modo semplice per implementarlo dagli altri primitivi.

function weakref(data) 
    local weak = setmetatable({content=data}, {__mode="v"}) 
    return function() return weak.content end 
end 

Creiamo una tabella debole con solo i dati in essa contenuti. Quindi restituiamo una funzione che, quando chiamata, restituisce il contenuto di quella tabella.

(Nota, riferimenti deboli non possono essere interrotti fino garbage collection, e letterali non sono mai garbage collection.)

+0

È un peccato che questa risposta non sia stata accettata: è migliore di quella accettata, E è arrivata un minuto prima. – fluffy

+1

L'altra risposta ha alcune cose piuttosto importanti che lo fanno ... in particolare, ha il potenziale di creare meno spazzatura, poiché la mia soluzione crea un oggetto e una chiusura su quell'oggetto per ogni chiamata, mentre la soluzione accettata crea solo la tabella . (Entrambi creano anche una nuova metatabia ogni volta, ma potrebbe essere estratto e riutilizzato). – kazagistar

+0

Ah, buoni punti. Per lo più avevo solo bisogno di conoscere '__mode =" v "' - nel mio caso d'uso sto facendo un pool di immagini e volevo solo una tabella debole in cui tutti i valori in una tabella fossero collezionabili. – fluffy