Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Deleu

[Resolvido] Funções dentro de Funções e acesso a variáveis globai

Recommended Posts

segue o código:

 


    private function fazAlgo():void{
    	CursorManager.setBusyCursor();
    	gateway.call("Clas.Metodo", new Responder(UsaRetornoPHP, onFault));

    	function UsaRetornoPHP(result:*):void{
	    	if(result is Array){
		    	if(result == null){	    		
		    		Alert.show("Dado não encontrado.");
		    	}else{			    					    		
			    	var array_temp:ArrayCollection = new ArrayCollection(result);
					this.varA = array_temp[0].varA;
		    	}
	    	}else{
	    		Alert.show("Retorno não esperado");
	    	}
    	}

 

Dado o código acima, porque quando saio da função UsaRetornoPHP, que se encontra dentro da função fazAlgo, a variável varA passa a ser nula?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Problema 'entendido'.

O que acontece é que não ocorre cópia dos valores do Array de retorno do PHP, mas sim objeto de referência. A variável Global passa a referenciar uma parte do Objeto e, por ser um objeto de escopo, este perde seu valor quando a função acaba.

Ainda aceito sugestões de soluções.

 

Obrigado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

private function fazAlgo():void{
    CursorManager.setBusyCursor();
    gateway.call("Clas.Metodo", new Responder(UsaRetornoPHP, onFault));
}

private function UsaRetornoPHP(result:*):void{
   if(result is Array){
          if(result == null){                     
                Alert.show("Dado não encontrado.");
           }else{                                                                          
                var array_temp:ArrayCollection = new ArrayCollection(result);
                 this.varA = array_temp[0].varA;
           }
   }else{
         Alert.show("Retorno não esperado");
   }
}

 

É um mau design utilizar método dentro de método.

 

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

É um mau design utilizar método dentro de método.

 

;)

 

Sério? Por quê? Eu nunca tinha utilizado até ver no Fórum da Stackoverflow. Achei superinteressante porque quando preciso pegar algo do PHP (ou do MySQL), uso uma função que precisa de um Responder (getResult). Essa função getResult só será utilizada SE e SOMENTE SE a função principal é chamada. Meio confuso, mas explico:

 

Supomos uma tela de cadastro de Clientes. No Flex, tenho uma função

private function getClientes():void{
    gateway.call("clientes.getClientes", new Responder(getResultGetClientes, onFault));
}

private function getResultGetClientes(result:Array):void{
   dataProviderClientes = new ArrayCollection(result);
}

 

Neste caso, a função getResultGetClientes só é chamada SE e SOMENTE SE a função getClientes for chamada. Ela não serve para mais nada a não ser pegar o retorno do PHP e colocar no Array. 80% dos casos são esses e, particularmente, notei que a facilidade de se ler um código desta forma é incrivelmente mais fácil. Daí me dizem: Coloque as funções getResult logo abaixo de todas as "Get", e eu respondo: Eu usava assim antes de descobrir que posso declarar funções dentro de funções. Ainda assim é mais fácil e prático ler o código com funções dentro de funções.

 

Enfim, existe algum motivo específico para não ser uma boa ideia fazê-lo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema já foi resolvido, mas ainda aceito resposta sobre o porquê é um mal design usar método dentro de método, ou se no meu caso, que o sub-método só será chamado se e somente se o método 'pai' dele for chamado, não tem problema.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema já foi resolvido, mas ainda aceito resposta sobre o porquê é um mal design usar método dentro de método, ou se no meu caso, que o sub-método só será chamado se e somente se o método 'pai' dele for chamado, não tem problema.

 

Não precisa de preocupar (tanto) com isso. Ao escrever seu código pense, por exemplo, como vai conseguir ler esse mesmo trecho, sei lá, um ano depois. Dispor suas funções como métodos privados vai permitir não só que você leia mais facilmente, como vai permitir que você use, por exemplo, Asdoc para documentá-las. Claro, a partir disso, use o bom senso. Eu mesmo, ocasionalmente, crio funções dentro de outras funções quando eu julgo que fica melhor assim. Você é o programador, você decide.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema já foi resolvido, mas ainda aceito resposta sobre o porquê é um mal design usar método dentro de método, ou se no meu caso, que o sub-método só será chamado se e somente se o método 'pai' dele for chamado, não tem problema.

 

Não precisa de preocupar (tanto) com isso. Ao escrever seu código pense, por exemplo, como vai conseguir ler esse mesmo trecho, sei lá, um ano depois. Dispor suas funções como métodos privados vai permitir não só que você leia mais facilmente, como vai permitir que você use, por exemplo, Asdoc para documentá-las. Claro, a partir disso, use o bom senso. Eu mesmo, ocasionalmente, crio funções dentro de outras funções quando eu julgo que fica melhor assim. Você é o programador, você decide.

 

Exatamente, mas quando se trata de orientação a objeto, a ideia é o melhor reaproveitamento de código, encapsulamento e baixo acoplamento. Uma função dentro da outra fica restrita apenas para aquela necessidade, podendo nem mesmo ser reaproveitado por classes que a extenderem, mesmo sendo um callback ;)

 

Seguindo uma camada Service onde sua classe deve realizar as tarefas que interagem com o PHP (por exemplo um CRUD), é muito melhor usar um callback que identifica a tarefa do que várias funções com subfunções praticamente idênticas.

 

Mas se a tarefa for realmente muito específica não a ponto de ser necessário uma função própria para ela, sem dúvida uma função interna seria interessante, mas neste caso eu utilizaria uma função anônima para ficar o mais compacto e legível possível ;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema já foi resolvido, mas ainda aceito resposta sobre o porquê é um mal design usar método dentro de método, ou se no meu caso, que o sub-método só será chamado se e somente se o método 'pai' dele for chamado, não tem problema.

 

Não precisa de preocupar (tanto) com isso. Ao escrever seu código pense, por exemplo, como vai conseguir ler esse mesmo trecho, sei lá, um ano depois. Dispor suas funções como métodos privados vai permitir não só que você leia mais facilmente, como vai permitir que você use, por exemplo, Asdoc para documentá-las. Claro, a partir disso, use o bom senso. Eu mesmo, ocasionalmente, crio funções dentro de outras funções quando eu julgo que fica melhor assim. Você é o programador, você decide.

 

Exatamente, mas quando se trata de orientação a objeto, a ideia é o melhor reaproveitamento de código, encapsulamento e baixo acoplamento. Uma função dentro da outra fica restrita apenas para aquela necessidade, podendo nem mesmo ser reaproveitado por classes que a extenderem, mesmo sendo um callback ;)

 

Seguindo uma camada Service onde sua classe deve realizar as tarefas que interagem com o PHP (por exemplo um CRUD), é muito melhor usar um callback que identifica a tarefa do que várias funções com subfunções praticamente idênticas.

 

Mas se a tarefa for realmente muito específica não a ponto de ser necessário uma função própria para ela, sem dúvida uma função interna seria interessante, mas neste caso eu utilizaria uma função anônima para ficar o mais compacto e legível possível ;)

 

Certo, então devemos concordar que usar funções internas em métodos podem não ser um design tão mal assim. Levando em consideração tudo isso, ele pode decidir usá-las:

  1. Quando for um callback totalmente singular, que não possa ser reaproveitado e onde ele não pretendia mantê-lo acessível para as subclasses como um método não-privado; ou
  2. Quando ele querer sinalizar um ouvinte de evento com referência fraca (para facilitar a coleta pelo GC);

E talvez vários outros motivos que eu não conheça. Nomear ou não essa função não deve ter muitos reflexos reais.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Certo, então devemos concordar que usar funções internas em métodos podem não ser um design tão mal assim. Levando em consideração tudo isso, ele pode decidir usá-las:

  1. Quando for um callback totalmente singular, que não possa ser reaproveitado e onde ele não pretendia mantê-lo acessível para as subclasses como um método não-privado; ou
  2. Quando ele querer sinalizar um ouvinte de evento com referência fraca (para facilitar a coleta pelo GC);

E talvez vários outros motivos que eu não conheça. Nomear ou não essa função não deve ter muitos reflexos reais.

 

 

Estes são casos onde a oop é irrelevante e a maioria dos projetos de bom padrão ela é o fator principal. Veja os testes que realizei:

 

private var variavel:String = "variavel1";

private function startApp():void{
//teste();//irá chamar o método da classe
exemplo();
}

private function exemplo():void{
var variavel:String = "variavel2";
this.teste();//irá chamar o método da classe
teste();//irá chamar o método interno
trace(variavel);//variavel2
trace(this.variavel);//variavel1
function teste():void{
	var variavel:String = "variavel3";
	trace(super.alpha);//Property alpha not found on Object and there is no default value.
	trace("sub");
	setTimeout(teste,5000);// irá apo´s 5segs chamar esta mesma função
	//this.teste();// erro: teste is not a function.
	//super.teste();//erro: Method teste not found on Object
	//trace(variavel);//variavel3
	//trace(this.variavel);//undefined
	//trace(super.variavel);//Property variavel not found on Object and there is no default value.
}
}

private function teste():void{
trace("super");
}

 

Como podem ver o uso do super e do this resultam em diversos problemas e confusões (resultado de um mal design), um dos motivos é que uma função interna "não faz parte da classe", veja porque:

Insira no método da classe: trace(this);//[Object NomeDaSuaClasse]

agora coloque no método interno: trace(this);//[object global]

 

Imagine que você tenha feito numa classe final que é herdada e gostaria de chamar um método da superclasse, ou queira acessar uma variável da classe e não do escopo você irá chegar no ponto: não tem como. Talvez com umas gambiarras daqui e dali você consiga mas é inevitável dizer que isto é um mau design.

 

A comportamento das funções anônimas é muito semelhante, a diferença principal é que elas não possuem nome (rsrs).

 

Você mesmo teve um dos problemas citados Deleu exatamente na linha de código:

 

this.varA = array_temp[0].varA;

o this pertence ao: [object global] e não a sua lcasse quando invocado dentro de uma função interna

 

Não estou condenando o uso de funções anônimas e internas mas é o importante é saber usá-las:

-Tente não usá-las quando for necessário salvar algum valor numa variável da classe ou acima de seu escopo

-No caso de uma interna com um nome que jamais irá ser o mesmo de algum método da classe

-Quando seu callback for ridiculamente simples (ou seja: na minoria das vezes)

 

 

São coisas que pouca gente usa e em poucos casos porque são realmente específicos e se usados de forma incorreta acabem na maioria das vezes sendo problemáticos ;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Certo, então devemos concordar que usar funções internas em métodos podem não ser um design tão mal assim. Levando em consideração tudo isso, ele pode decidir usá-las:

  1. Quando for um callback totalmente singular, que não possa ser reaproveitado e onde ele não pretendia mantê-lo acessível para as subclasses como um método não-privado; ou
  2. Quando ele querer sinalizar um ouvinte de evento com referência fraca (para facilitar a coleta pelo GC);

E talvez vários outros motivos que eu não conheça. Nomear ou não essa função não deve ter muitos reflexos reais.

 

 

Estes são casos onde a oop é irrelevante e a maioria dos projetos de bom padrão ela é o fator principal. Veja os testes que realizei:

 

private var variavel:String = "variavel1";

private function startApp():void{
//teste();//irá chamar o método da classe
exemplo();
}

private function exemplo():void{
var variavel:String = "variavel2";
this.teste();//irá chamar o método da classe
teste();//irá chamar o método interno
trace(variavel);//variavel2
trace(this.variavel);//variavel1
function teste():void{
	var variavel:String = "variavel3";
	trace(super.alpha);//Property alpha not found on Object and there is no default value.
	trace("sub");
	setTimeout(teste,5000);// irá apo´s 5segs chamar esta mesma função
	//this.teste();// erro: teste is not a function.
	//super.teste();//erro: Method teste not found on Object
	//trace(variavel);//variavel3
	//trace(this.variavel);//undefined
	//trace(super.variavel);//Property variavel not found on Object and there is no default value.
}
}

private function teste():void{
trace("super");
}

 

Como podem ver o uso do super e do this resultam em diversos problemas e confusões (resultado de um mal design), um dos motivos é que uma função interna "não faz parte da classe", veja porque:

Insira no método da classe: trace(this);//[Object NomeDaSuaClasse]

agora coloque no método interno: trace(this);//[object global]

 

Imagine que você tenha feito numa classe final que é herdada e gostaria de chamar um método da superclasse, ou queira acessar uma variável da classe e não do escopo você irá chegar no ponto: não tem como. Talvez com umas gambiarras daqui e dali você consiga mas é inevitável dizer que isto é um mau design.

 

A comportamento das funções anônimas é muito semelhante, a diferença principal é que elas não possuem nome (rsrs).

 

Você mesmo teve um dos problemas citados Deleu exatamente na linha de código:

 

this.varA = array_temp[0].varA;

o this pertence ao: [object global] e não a sua lcasse quando invocado dentro de uma função interna

 

Não estou condenando o uso de funções anônimas e internas mas é o importante é saber usá-las:

-Tente não usá-las quando for necessário salvar algum valor numa variável da classe ou acima de seu escopo

-No caso de uma interna com um nome que jamais irá ser o mesmo de algum método da classe

-Quando seu callback for ridiculamente simples (ou seja: na minoria das vezes)

 

 

São coisas que pouca gente usa e em poucos casos porque são realmente problemáticos ;)

 

Sim, funções internas não têm acesso ao objeto, uma vez que ela não pertence ao objeto. Mas, diferente dos métodos, têm acesso às variáveis do mesmo escopo que foram criadas.

function bar():void {
var var1:String = "teste";
function foo():void {
	trace(var1);
}
foo();
}
bar(); // output: teste

 

De novo: Essas funções são usadas em vários casos e não representam necessariamente um mal design. Na classe Array, por exemplo, você deve encontrar vários métodos que recebem funções como argumento e que podem receber funções internas tranquilamente, sem que isso represente um sacrifício na OOP.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.