• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

pedrotuga

Uma pergunta básica sobre rails

4 mensagens neste tópico

Bem...ainda estou à espera que alguem me responda à outra pergunta que fiz sobre ruby.

Entretanto já estou aqui com o rails a rolar e já tenho dúvidas no básico dos básicos.

Os controlloer normalmente têm acções definidas mais ou menos assim:

class WeblogController < ActionController::Base
  def index
    @posts = Post.find :all
    respond_to do |format|
      format.html
      format.xml { render :xml => @posts.to_xml }
      format.rss { render :action => "feed.rxml" }
    end
  end
end

Ok, isto é obvio o que faz, conforme o formato carrega a respectiva vista, do tipo adequado. Muito bem.

Só não entendo é por que raio é isso que acontece. Aos meus olhos o que eu ali vejo é:

pegar no valor devolvido pela função respond_to e envia-lo para o bloco usando o format como parâmetro.

Ou seja, aquelas três instruções deviam ser executadas:

De acordo com o que acontece aparentemente nem sequer são instruções.

Alguem me pode explicar melhor o que se está a passar aqui?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Mas se reparares isso não responde à pergunta.

O problema não é o que o respond_to faz, o problema é perceber porque é que só uma das instruções do bloco é executada.

Agora há tempos fui ao canal de IRC do rails na freenode e um gajo esteve lá a explicar-me como é que os controlers são implementados, só que já não me lembro :s

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas, eu já não mexo com RoR há mesmo muito tempo, mas sou fã da lingagem Ruby.

Vamos lá ver se consigo responder à tua pergunta.

Só não entendo é por que raio é isso que acontece.

Experimenta ler a documentação e, se mesmo assim não conseguires perceber como é que algo funciona, vai directamente à fonte. Assim pode-se praticar um skill bastante importante k é "code-reading" e podes até aprender alguns truques pelo caminho ;)

Aos meus olhos o que eu ali vejo é: pegar no valor devolvido pela função respond_to e envia-lo para

o bloco usando o format como parâmetro.

Atenção que não é bem isso que acontece. O valor devolvido pelo metodo respond_to não é enviado para o bloco. O que acontece é que alguns na função respond_to é feito uma chamada explicita ao bloco que passaste, passando um objecto que depois deste o nome de "format" (ja falo mais sobre este "format" mais em frente).

Ou seja, aquelas três instruções deviam ser executadas:

De acordo com o que acontece aparentemente nem sequer são instruções.

O que está dentro do bloco são instruções, não há nenhuma excepção. E essas 3 instruções são realmente executadas. O que é preciso ver é o que acontece quando são executadas, ou seja, o que acontece quando chamas um metodo na variavel format?

Para isso temos que ver a documentação (link em cima), onde há um botão "view source" que te mostra o codigo do respond_to:

102	      def respond_to(*types, &block)
103	        raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
104	        block ||= lambda { |responder| types.each { |type| responder.send(type) } }
105	        responder = Responder.new(self)
106	        block.call(responder)
107	        responder.respond
108	      end

Olhando para o codigo, sabemos que o format é um objecto do tipo Responder. Agora que raio é Responder? Não é uma classe documentada, e quando fui ver ela está definida no mesmo ficheiro que respond_to está definido.

Podes ver o ficheiro online aqui: http://trac.metasploit.com/browser/framework3/trunk/data/msfweb/vendor/rails/actionpack/lib/action_controller/mime_responds.rb

Não te assustes com o codigo, pode parecer um bocado complexo, especialmente se fores novo a Ruby, mas no fim até não é nada de mais. O que o Responder faz é, em runtime, ele cria os metodos tipo format.xml, format.html, etc. usando técnicas de meta-programação (Linha 150). Quando chamas um desses metodo, lá dentro é feito outra chamada a uma função chamada "custom" (linha 152) e é aqui que está a tua resposta.

O metodo custom recebe um bloco de codigo e guarda esse bloco (sem o executar) numa hash (linha 132), para que, mais tarde, quando é feito um pedido para visualizar essa acção em xml, o RoR possa executar o bloco que realmente forneceste. Se por acaso não passares nenhum bloco, como no "format.html", o metodo "custom" cria um bloco na mesma que vai pedir o codigo html da acção correspondente (Linha 135).

Portanto, o bloco de codigo que forneceste ao respond_to foi realmente executada. Os blocos que passaste aos metodos do "format" é que não são executadas porque foram guardadas numa hash para serem utilizadas mais tarde. Não há magia nenhuma aqui :P

Basicamente é isso, espero que isto ajudou.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora