2013-06-05 16 views
6

Z Lua 5.1 documentation for load():Zachowanie obciążenia(), gdy funkcja zwraca nil kawałek

Ładunki kawałek użyciem funkcji func dostać swoje kawałki. Każde wywołanie do func musi zwracać ciąg, który łączy się z poprzednimi wynikami. Zwrot pustego łańcucha, nil, lub żadna wartość nie sygnalizuje końca porcji.

Z moich testów nie jest to prawda. Lub raczej dokumentacja jest co najmniej myląca.

Rozważmy następujący przykład skrypt:

function make_loader(return_at) 
    local x = 0 

    return function() 
     x = x + 1 

     if x == return_at then return 'return true' end 

     return nil 
    end 
end 

x = 0 
repeat 
    x = x + 1 
until not load(make_loader(x))() 

print(x) 

Wyjście jest liczba kolejnych wywołań funkcji zwracanej przez make_loader() że zwracany nil przed load() rezygnuje i zwraca funkcję powracającego nic.

Można oczekiwać, że wynik tutaj będzie "1", jeśli dokumentacja ma być wykonana według wartości nominalnej. Jednak wynik to "3". To implikuje, że argument do load() jest wywoływany, dopóki nie zwróci go nilprzed przed load().

Z drugiej strony, jeśli funkcja kawałek natychmiast, a następnie nil na kolejnych wywołań zwraca łańcuch, to zajmuje tylko jeden nil przestać ładowania:

function make_loader() 
    local x = 0 

    return { 
     fn=function() 
      x = x + 1 

      if x == 1 then return 'return true' end 

      return nil 
     end, 
     get_x=function() return x end 
    } 
end 

loader = make_loader() 
load(loader.fn) 
print(loader.get_x()) 

Drukuje „2”, jak bym się spodziewał.

Moje pytanie brzmi: czy dokumentacja jest nieprawidłowa? Czy to zachowanie jest pożądane z jakiegoś powodu? Czy to po prostu błąd w load()? (Wydaje się pojawiać zamierzone, ale nie mogę znaleźć żadnej dokumentacji wyjaśniając dlaczego.)

+0

Czy próbowałeś Lua 5.2? –

+0

@NicolBolas No. – cdhowie

+2

Możesz spróbować. To prawdopodobnie błąd w Lua 5.1. –

Odpowiedz

6

To jest błąd w wersji 5.1. Zostało to poprawione w wersji 5.2, ale nie uwzględniliśmy poprawki w 5.1.

+0

Poprawkę można znaleźć pod adresem http://www.lua.org/bugs.html#5.1.5-2. – lhf

3

mam nieco inne wyniki od Ciebie, ale są one nadal nie całkiem co dokumentacja zakłada:

function make_loader(return_at) 
    local x = 0 
    return function() 
     x = x + 1 
     print("make_loader", return_at, x) 
     if x == return_at then return 'return true' end 
     return nil 
    end 
end 

for i = 1, 4 do 
    load(make_loader(i)) 
end 

ta zwraca następujące wyniki:

make_loader 1 1 
make_loader 1 2 
make_loader 2 1 
make_loader 2 2 
make_loader 2 3 
make_loader 3 1 
make_loader 3 2 
make_loader 4 1 
make_loader 4 2 

Dla 1 nazywa się dwa razy, ponieważ pierwsza była return true a drugi zerowe. W przypadku 2 jest on wywoływany trzy razy, ponieważ pierwszy raz był nil, następnie return true, a następnie nil ponownie. Dla wszystkich pozostałych wartości jest to wywoływane dwa razy: wygląda na to, że pierwszy nil jest ignorowany, a funkcja jest wywoływana co najmniej jeszcze raz.

Jeśli tak jest rzeczywiście, dokumentacja musi to odzwierciedlać. Spojrzałem na kod źródłowy, ale nie widziałem niczego, co mogłoby wyjaśnić, dlaczego pierwszy zwrócony nil jest ignorowany (testowałem również z pustym ciągiem i bez wartości z tym samym wynikiem).

+0

+1 Dobra informacja. Nie jestem pewien, czy to technicznie odpowiedź, więc nie będę tego oznaczać, ale dodatkowe informacje są zdecydowanie przydatne. – cdhowie