Sistema atribuindo valor a array sem que isso seja solicitado

Estou com problemas em uma função que recebe alguns arrays como parâmetro. Algumas vezes esse parâmetro vai vazio ou nulo e isso é tratado com o comando DEFAULT.

O que está acontecendo é que uma dessas variáveis está recebendo o valor de outro sem que isso seja feito no programa.

Eu montei um pequeno exemplo do problema. Quando o N valer 2, a variável aParam02 vai estar com valores, porém está errado já que ela inicia o processo vazia e não recebe nenhum valor durante o processamento.

Coloquei o fonte criado para teste e um print do TDS sobre o caso.

Agradeço a ajuda.

:warning: Atenção: Esta publicação foi transferida automaticamente do fórum antigo, mas os anexos não foram incluídos.

Guilherme,

Faço um teste com nomes menores das variáveis, use aPar01, aPar02 e aPar03 e veja se o problema persiste.

Abraço,

Boa tarde,

Faz todo o sentido a variável aParam02 possuir valores quando N estiver igual a dois, visto que na iteração anterior você atribuiu a referência de aParam02 para a aParam03:


aParam03 := aParam02

Esse tipo de atribuição faz uma cópia da referência do array e não de seus valores, logo ao alterar os valores da aParam03, isso também será alterado em aParam02:


IF LEN(aParam03) == 0
    AADD(aParam03, N * 1)
    AADD(aParam03, N * 2)
    AADD(aParam03, N * 3)
ENDIF


Se você deseja trabalhar com os valores do array em outra variável, sem que a principal tenha seus valores alterados, você precisa fazer uma cópia do array, isso é feito com a função aClone:


aParam03 := aClone( aParam02 )


Com isso, seu código deverá ficar da seguinte forma:


#INCLUDE "TOPCONN.CH"
#INCLUDE "PROTHEUS.CH"

USER FUNCTION AJUSTE10
    LOCAL aParam01 := {"A","B"}

    U_AJUSTE11(aParam01)
RETURN

USER FUNCTION AJUSTE11(aParam01,aParam02)
    LOCAL N := 0
    LOCAL aParam03 := {}

    DEFAULT aParam02 := {}

    FOR N := 1 TO LEN(aParam01)
        aParam03 := aClone(aParam02)

        IF LEN(aParam03) == 0
            AADD(aParam03, N * 1)
            AADD(aParam03, N * 2)
            AADD(aParam03, N * 3)
        ENDIF

        aParam03 := {}
    NEXT N

    _DEBUG_ := .T.
RETURN

Obs.: A atribuição de valores com IGUAL copia a referência em variáveis do tipo array e também do tipo objeto.

Não acho que faz sentido, uma vez que estou atribuindo à variável aParam03 os valores de aParam02 e não o contrário. Como aParam02 está vazia, aParam03 deveria ficar vazia e aParam02 nunca deveria ter valores.

Guilherme, como o Daniel falou, neste tipo de atribuição para um array em advpl, você não passa o valor do array e sim a referência do endereço na memória e isto não é exclusivo do advpl, existem situações inclusive na orientação a objetos do java como exemplo a própria atribuição de um objeto no outro que funcionam desta maneira.

atribuindo à variável aParam03 os valores de aParam02, para isso utilize o aClone, senão você estará simplesmente apontando para o endereço de memória da aParam02.

Guilherme, faça o teste com o aClone e veja o resultado, imagine que quando você faz uma atribuição de array, é semelhante a você enviar um parâmetro para a função por referência, você acaba trabalhando em uma variável X, porém isso reflete também na variável Y.

O teste com o aClone funcionou, mas eu confesso que nunca tinha visto esse tipo de situação no Advpl nem em outras linguagens que já trabalhei.

Obrigado pelo retorno.