Tag: Ruby

Ruby, Jruby e Processing = ruby-processing

Um dos motivos que me fizeram ficar distante do blog por uns tempos foi o meu mestrado, cujo semestre acabou essa semana. E como estou trabahando direto com Java atualmente, tive que usar a imaginação para continuar praticando meus conhecimentos em Ruby. Para quem não sabe, estou fazendo mestrado em Sistemas Interativos de Visualização, com muitas cadeiras ligadas a Computação Gráfica, Animação e Visualização de Dados. Em muito dos trabalhos, utilizei uma das minha ferramentas favoritas, o Processing, mais precisamente sua alternativa rubista: o ruby-processing.

O Poder do JRuby

Uma das melhores vantagens fornecidas pelo JRuby é a possibilidade de utilizarmos as trocentas ferramentas já existentes no mundo Java utilizando Ruby. E foi exatamente isso que Jeremy Ashkenas fez. Perceba que a integração é relativamente simples entre as duas linguagens:

require 'java'

module Processing

  # Conditionally load core.jar
  require "#{RP5_ROOT}/lib/core/core.jar" unless Processing.online? || Processing.embedded?
  import "processing.core"
  .
  .
  .
class App < PApplet
  .
  .

Read more...

Leitor de RSS Feito Com Ruby e Sinatra

Após o meu primeiro post/tutorial que descreveu como criar uma párgina de perfil usando Sinatra, Haml e Sass, vou me aprofundar mais no tema criando uma outra aplicação de exemplo que explora melhor os conceitos por trás do Sinatra.

O exemplo anterior se resumia a simples GETs Http, mas nós sabemos que aplicações web são muito mais que isso, não é?

Então vamos ao que interessa.

Pré-Requisitos e Preparativos

Será necessário a instalação do sqlite3 em seu computador. Os passos para fazer isso fogem do escopo deste tutorial, mas você não encontrará dificuldades para esse procedimento(usuários de mac não precisam). Após a instalação, crie via linha de comando uma database, como no exemplo abaixo:

sqlite3 blue_eyes

SQLite version 3.4.0
Enter “.help” for instructions
sqlite> .quit

Usaremos algumas gems para nao reinventarmos a roda:

- sinatra – Nosso tão amado e querido micro-framework
- feedzirra – Parsing de RSS
- sequel – Para gerenciamento simples do sqlite com ruby – http://sequel.rubyforge.org
- Haml – Linguagem de marcação para nossos templates

Após instalarmos cada uma das gems necessárias, começaremos o desenvolvimento da aplicação.

Leitor de RSS Feito Totalmente em Ruby!

O idéia é criar um leitor de RSS básico, com as features mínimas necessárias para o seu funcionamento. Melhorias futuras serão tratadas em outros posts. Para que possamos gerenciar nossos feeds, criaremos um Model simples, representando objetos “feed”. Percebam que, assim como os conhecidos exemplos do ActiveRecord usado no Rails, aqui a gente também extende uma classe model do nosso framework de acesso ao BD, o Sequel. É possível notar também a semelhança com um Migration na definição do schema da tabela.

./feed.rb

class Feed < Sequel::Model
  unless table_exists?
      set_schema do
        primary_key :id
        text :url
        text :name
      end
      create_table
    end
end

Pronto. Nosso Model já está pronto, agora vamos para o Controller. Como essa é uma implementação bem simples, usaremos apenas a raiz do site para apresentar o conteúdo. Isso pode ser comprovado nos GETS que esperam apenas um parâmetro, no caso o "id" do feed no nosso banco.

./blue_eyes.rb

require 'sinatra'
require 'feedzirra'
require 'sequel'

configure do
  Sequel.sqlite('blue_eyes.db')
end
require 'feed'

get '/style.css' do
   content_type 'text/css', :charset => 'utf-8'
   sass :style
end

get '/' do
   @feeds = Feed.all
     @feed = Feedzirra::Feed.fetch_and_parse("http://www.tbueno.com/blog/feed/")
   haml :index
end

get '/:id' do
    @feeds = Feed.all
    @model = Feed.find(:id => params[:id])
    @feed = Feedzirra::Feed.fetch_and_parse(@model.url)
    haml :index
end

post '/add_feed' do
  f = Feedzirra::Feed.fetch_and_parse(params[:feed_url])
  feed = Feed.new(:url => f.feed_url, :name => f.title)
  feed.save
  redirect '/'
end

Outra novidade em relação ao tutorial anterior é o uso do “configure”, que é uma espécie de “initializer” do Rails e é executado, como o nome diz, apenas uma vez no início. Usaremos ele para conectarmos ao nosso banco.

Read more…

Acessando o Orkut com Ruby e Scraping

Se você é brasileiro, provavelmente deve fazer parte do que foi chamado de “WTF Crazy Brazilian Invasion“, lá pelos idos de 2006/2007, ao site de relacionamentos Orkut. Quando assumimos a liderança no número de usuários do Orkut, logo um efeito colateral começou a se manifestar: o excesso de scams, spams e outras filhadaputices tão típicas de brasileiros e países do leste europeu.

Essa ploriferação do mal, fez com que o Google começasse a aprimorar a parte de segurança do site, tornando ele hoje um dos sub-sites do conglomerado mais difíceis de se acessar por vias “automatizadas”.

Mas que tipo de informação seria possível de obter do site?

Acessando o Orkut com Ruby

Uma das medidas adotadas pelo Google para evitar os bots que atazanavam a vida de todos, foi a adoção de chamadas via Ajax, muito mais difíceis de ser capturadas e entendidas. Passei um bom tempo tentando entender o fluxo de dados de login, através do firebug, mas sempre esbarrava em arquivos javascript como esse, obviamente ofuscados de propósito.

Antigamente, alguns já haviam conseguido quebrar o Orkut com Ruby e scraping, mas hoje os mesmos métodos não funcionam mais.

A solução encontrada para evitar as chamadas com Ajax foi acessar o “lado sem javascript” do site, no caso, a interface para dispositívos móveis do site.

Read more…

Entendendo como funcionam class_eval, module_eval e instance_eval

Para quem como eu, vem de linguagens não-dinâmicas, o que mais impressiona (e dificulta no início) é a capacidade de Ruby em se moldar e executar códigos dinamicamente. E seguindo a nossa saga pelos conceitos de metaprogramação, vamos explorar um pouco mais um recurso interessantíssimo de Ruby chamado eval.

Ruby Eval

O nome eval tem origem na palavra inglesa evaluation, que em uma tradução livre significa “avaliar o valor de algo”, no caso de Ruby, o valor de uma expressão ou trecho de código.

No caso de Ruby, a melhor definição seria “interpretar”, devido ao fato que além de avaliar, o código recebido também é executado, como no exemplo abaixo:

eval("puts 'Hello World'") # => Hello World

No post anterior sobre metaprogramação, eu utilizei o método instance_variable_set da classe Object.

Esse método pode ser utilizado para evitar repetições de código. No código abaixo eu mostro como é a implementação desse método e como ele é usado na prática:

Implementação redundante de um construtor de uma classe:

class CalendarEvent
  def initialize(start_time=0, end_time=0, attendees=0)
    @start_time = start_time
    @end_time = end_time
    @attendees = attendees
  end
end

Implementação melhorada com o uso de eval:

#Primeiro, adicionamos o seguinte código à classe Object,
#para torná-lo disponível para as instâncias de quaisquer classe
class Object
  private
  def set_instance_variables(binding, *variables)
    variables.each do |var|
      instance_variable_set("@#{var}", eval(var, binding))
   end
  end
end

#Depois podemos melhorar a nossa classe

class CalendarEvent
  def initialize(start_time=0, end_time=0, attendees=0)
    set_instance_variables(binding, *local_variables)
  end
end

c = CalendarEvent.new(4,5,2)

puts c.instance_eval "@start_time"   # => 4

Read more…

Tudo que você sempre quis saber sobre Metaprogramação mas tinha vergonha de perguntar

A arte de escrever programas que escrevem programas está presente desde o início da ciência da computação, com o objetivo de aumentar a produtividade diminuindo a quantidade de código a ser escrito. O prefixo grego meta está presente na nossa língua, tornando mais fácil o entendimento do conceito por nós brasileiros logo de cara, bastando apenas lembrar das aulas de literatura ou dos livros de Machado de Assis.

Machadão, o rei da Metaliteratura

Machadão, o rei da Metaliteratura

Metaclasses

Lembra daquela frase que dizia que “em Ruby tu é objeto”? Pois é, vamos olhar o seguinte código:

class Zombie
  def self.alive
    puts "i am alive"
  end
end

Zombie.class     # => Class
Zombie.alive      # => "i am alive"
z = Zombie.new
z.class              # => Zombie

Read more…