VBS: На променлива не се присвоява стойност чрез рекурсивен израз

Имам проблем с присвояването на стойност на променлива на VBS:

Dim varName  
varName = function(x, y)
varName = function(x, y)

функция е рекурсивна функция, която се извиква:

Function function(x, y)
    If IsObject(dicColumnIndices) Then
        function = CInt(dicColumnIndices.Item(y))
    Else
        Set oCDSGrid = %MyAppObject%
        Set dicColumnIndices = CreateObject("Scripting.Dictionary")
        intColumnCount = oCDSGrid.ActiveSheet.Columns.Count
        For i = 0 To intColumnCount - 1
            dicColumnIndices.Add oCDSGrid.ActiveSheet.Columns.Item(i).Label, i
        Next

        function x, y
    End If
End Function

Доколкото виждам, присвояването на стойност на променлива се случва само при втория опит. Реших, че има нещо общо с функцията ми, която се самоизвиква рекурсивно (проблемът изчезва, в случай че премахна рекурсивното извикване), но много бих искал да науча какви са корените на това поведение.

Потърсих както StackOverflow, така и интернет без успех.

Редактиране: За да разреша този проблем, трябваше да премахна рекурсивното повикване:

Function function(x, y)
If IsObject(dicColumnIndices) Then
    function = CInt(dicColumnIndices.Item(y))
Else
    Set oCDSGrid = %MyAppObject%
    Set dicColumnIndices = CreateObject("Scripting.Dictionary")
    intColumnCount = oCDSGrid.ActiveSheet.Columns.Count
    For i = 0 To intColumnCount - 1
        dicColumnIndices.Add oCDSGrid.ActiveSheet.Columns.Item(i).Label, i
    Next

    function = CInt(dicColumnIndices.Item(y))
End If
End Function

Редактиране 2: И накрая, с помощта на MSDN получих грешната част - това е второто повикване

function x, y

който връща стойността в нищо, трябва да се промени на:

function = function x, y

Благодаря на всички!


person Eugene A    schedule 08.08.2012    source източник
comment
Все пак не трябва да използвате Ключови думи на VBScript като пример за именуване на променливи или функции. Това адски обърква хората, които се опитват да намерят отговор. И защо искате да използвате рекурсия е пъзел за мен. Защо не използвате: If not IsObject(someVar) then Set someVar = CreateObject("Scripting.Dictionary") '... etc и след End If поставите кода, който обработва someVar като току-що инициализиран обект, във вашия случай: YourFunction = CInt(dicColumnIndices.Item(y))   -  person AutomatedChaos    schedule 09.08.2012
comment
Съгласен, ще имам предвид за бъдещите си публикации. Също така благодаря за съвета за опростяване!   -  person Eugene A    schedule 09.08.2012


Отговори (1)


Една функция не трябва да се нарича функция, а името на променливата е скапано име за променлива. По-конкретно: във VBScript функцията не е функция (не връща нещо), ако не „присвоите на името на функцията“:

  Dim s : s = "abcdefg"
  Dim l : l = recLen(s)
  WScript.Echo "recursive length of", qq(s), "=>", l, CStr(l = Len(s))

  Function recLen(s)
    If "" = s Then
       recLen = 0
    Else
       recLen = 1 + recLen(Mid(s, 2))
    End If
  End Function

(Дължината на празен низ е 0; за по-дълги низове е 1 + дължината на „опашката“ на низа)

Актуализация (благодарение на AutomatedChaos):

Function qq( vStringable )
  qq = """" & vStringable & """"
End Function

Актуализация II (за отговор на въпроса на Юджийн в коментар):

За да направите функция да връща нещо, ще трябва да присвоите стойността за връщане на променлива със същото име като функцията. Вашият оригинален код не го направи (дори ако името "функция" е заменено с "истинското" име).

person Ekkehard.Horner    schedule 08.08.2012
comment
Благодаря Ekkehard, разбира се, моите функции и променливи не се наричат ​​така. В крайна сметка замених рекурсивното извикване с блока за обработка: s/function x, y/GetColumnIndex = CInt(dicColumnIndices.Item(y))/ и този път проработи. Все още обаче не разбирам как функцията не е присвоена стойността с помощта на второто (рекурсивно) извикване. - person Eugene A; 08.08.2012
comment
Хубаво обяснение, но вашият код не работи! Първоначално бях развълнуван от въвеждането на функция на VBScript, която не познавах: qq, но за съжаление не беше. Това, което не знаех, беше използването на Wscript.Echo с множество параметри. - person AutomatedChaos; 08.08.2012