Ruby para programadores PHP
03/08/07
A maneira mais fácil de se aprender uma nova linguagem é comparando-a com uma linguagem que você já conhece. Pelo menos é assim que faço! Para os que são como eu, aqui vai uma série de comparações/equivalências entre as linguagens Ruby e PHP.
Estruturas de controle
Condicionais
# php
# setting some variables
$n1 = 1;
$n2 = 2;
$n3 = 3;
# if condition
if ($n1 > $n2)
echo 'n1 > n2',"\n";
elseif ($n1 > $n3)
echo 'n1 > n3', "\n";
else
echo 'n1 =< n2; n1 =< n3', "\n";
# one-line if
echo n3 > n2? "n3 > n2\n" : "n3 <= n2\n";
# switch..case
switch($n1) {
case 1:
echo "n1 = 1", "\n";
break;
case 2:
echo "n1 = 2", "\n";
break;
default:
echo "n1 = {$n1}", "\n";
}
# ruby
# setting some variables
n1 = 1
n2 = 2
n3 = 3
# if condition
if n1 > n2
puts 'n1 > n2'
elsif n1 > n3
puts 'n1 > n3'
else
puts 'n1 =< n2; n1 =< n3'
end
# one-line if
puts n3 > n2 ? 'n3 > n2' : 'n3 <= n2'
# unless condition
unless n3 > n2
puts 'n3 > n2'
end
# different structure
puts 'n1 > n3' if n1 > n3
puts 'n1 =< n2' unless n1 > n2
# switch..case
case n1
when 1
puts 'n1 = 1'
when 2
puts 'n1 = 2'
else
puts 'n1 = %d' % n1
end
Estruturas de repetição
# php
# while
$i = 1;
while ($i < 5) {
echo $i, "\n";
$i += 1;
}
# do..while
$i = 1;
do {
echo $i, "\n";
$i += 1;
} while ($i < 5);
# for i++
for ($i = 1; $i <= 5; $i++) {
echo $i, "\n";
}
# for i--
for ($i = 5; $i >= 1; $i--) {
echo $i, "\n";
}
# each
foreach (range(1,5) as $i) {
echo $i, "\n";
}
# break/continue
$i = 0;
while ($i < 10) {
$i++;
# break
if ($i == 9) {
break;
}
# continue
if ($i % 2 == 0) {
continue;
}
echo $i, "\n";
}
# ruby
# while
i = 1
while i < 5
puts i
i += 1
end
# until
i = 1
until i > 5
puts i
i += 1
end
# loop
i = 1
loop do
break if i > 5
puts i
i += 1
end
# do..while
i = 1
begin
puts i
i += 1
end while i < 5
# do..until
i = 1
begin
puts i
i += 1
end until i > 5
# upto (for i++)
1.upto(5) do |i|
puts i
end
# downto (for i--)
5.downto(1) do |i|
puts i
end
# for..in (foreach)
for i in (1..5)
puts i
end
# each
(1..5).each do |i|
puts i
end
# break/next
i = 0
while i < 10 do
i += 1
break if i == 9 # break
next if i % 2 == 0 # next (continue)
puts i
end
Strings
Particularmente, penso que o PHP é muito mais completo para se lidar com strings quando o assunto é biblioteca padrão. Na maioria das vezes você possui alternativas — estender a classe, por exemplo — mas é um trabalho que alguém terá que fazer.
Manipulando strings
# php
# interpolate variables
$text = "php";
echo "i love $text", "\n";
echo "i love {$text}", "\n";
printf("i love %s\n", $text);
# basic functions
$text = 'i love php';
echo strtolower('I LOVE PHP'), "\n"; # lowercase text
echo strtoupper($text), "\n"; # uppercase text
echo ucfirst($text), "\n"; # capitalize text
echo strlen($text), "\n"; # string size
echo strrev($text), "\n"; # reversing text
echo str_repeat("php ", 3), "\n"; # repeat text
echo ord("a"), "\n"; # get ASCII value
echo chr("97"), "\n"; # get char from ASCII value
# remove spaces
$text = ' i love php ';
echo trim($text), "\n"; # both sides
echo ltrim($text), "\n"; # just left side
echo rtrim($text), "\n"; # just right side
# remove characters
$text = '__i love php__';
echo trim($text, '_'), "\n"; # both sides
echo ltrim($text, '_'), "\n"; # just left side
echo rtrim($text, '_'), "\n"; # just right side
# slicing strings
$text = 'i love php';
echo substr($text, 0, 6), "\n";
echo $text[0], "\n";
# search characters
echo strpos("php", "h"), "\n"; # find position
# ruby
# interpolate variables
text = "ruby"
puts "i love #{text}";
puts "i love %s" % text;
printf("i love %s\n", text);
# basic functions
text = 'i love ruby';
puts 'I LOVE RUBY'.downcase # lowercase text
puts text.upcase # uppercase text
puts text.capitalize # capitalize text
puts text.size # string size
puts text.reverse # reversing text
puts "ruby " * 3 # repeat text
puts "a"[0] # get ASCII value
puts 97.chr # get char from ASCII value
# remove spaces
text = ' i love ruby ';
puts text.strip # both sides
puts text.lstrip # just left side
puts text.rstrip # just right side
# remove characters
# ruby has no easy way of doing that besides regular expressions
# so we're gonna extend String class
# check this link out: http://simplesideias.com.br/
text = '||__i love ruby__||'
puts text.trim('_|') # both sides
puts text.ltrim('_|') # just left side
puts text.rtrim('_|') # just right side
# slicing strings
text = 'i love ruby';
puts text[0,6]
puts text[0,1]
# search characters
puts "ruby" =~ /y/ # find position
Gerando hashes com MD5 e SHA1
# php
echo md5("php"), "\n";
echo sha1("php");
# ruby
require 'digest/md5'
require 'digest/sha1'
puts Digest::MD5.hexdigest("ruby")
puts Digest::SHA1.hexdigest("ruby")
Expressões regulares
No PHP temos uma série de funções que lidam com expressões regulares como eregi, preg_match, preg_replace, dentre outras. O Ruby também tem métodos equivalentes:
preg_match vs match
Verificar se uma determinada string obedece um padrão
#php
if(preg_match("/^\d{2}\/\d{2}\/\d{4}$/", '01/01/2007')) {
print 'valid format'
} else {
print 'invalid format'
}
# ruby - method 1
if '01/01/2007' =~ /^\d{2}\/\d{2}\/\d{4}$/
puts 'valid format'
else
puts 'invalid format'
end
# ruby - method 2
if '01/01/2007'.match(/^\d{2}\/\d{2}\/\d{4}$/)
puts 'valid format'
else
puts 'invalid format'
end
Acessando os matches de uma expressão regular
# php
preg_match("/like/", "i like php", $matches);
print "match: " . $matches[0];
# ruby
matches = "i like ruby".match(/like/)
puts matches[0]
Atribuindo os matches de uma expressão regular à variáveis
# php
preg_match("/(\b\w+\b) (\b\w+\b)/", "nando vieira", $matches);
list($full_name, $first_name, $last_name) = $matches;
print $full_name . "\n";
print $first_name . "\n";
print $last_name;
# ruby
full_name, first_name, last_name = *"nando vieira".match(/(\b\w+\b) (\b\w+\b)/)
puts full_name
puts first_name
puts last_name
preg_replace vs gsub
Substituíndo padrões
# php
print preg_replace("/like/", "love", "i like php")
# ruby
puts "i like ruby".gsub(/like/, 'love')
Utilizando retrovisores (backreferences)
# php
print preg_replace("/(duck)/", "\$1 and one chicken", "one duck")
# ruby
puts "one duck".gsub(/(duck)/, "\\1 and one chicken")
preg_match_all vs scan
# php
$text = "item 1\nitem 2\nitem 3";
preg_match_all("/item (\d+)/sim", $text, $matches);
print_r($matches[1]);
# ruby
text = "item 1\nitem 2\nitem 3"
matches = text.scan(/item (\d+)/)
puts matches
Array e Hash
Utilizando arrays
# php
$companies = array('apple', 'microsoft', 'red hat', 'canonical');
echo count($companies), "\n"; # how many items?
echo $companies[0], "\n"; # first item
echo end($companies), "\n"; # last item
echo (int)empty($companies), "\n"; # size > 0?
# sorting array
sort($companies);
# removing duplicate items
$companies = array_unique($companies);
# applying a function
$companies = array_map('strtoupper', $companies);
# reversing
$companies = array_reverse($companies);
# joining
echo join(", ", $companies), "\n";
# slicing
echo join(", ", array_slice($companies, 1, 3)), "\n";
# removing last item
echo array_pop($companies), "\n";
# removing first item
echo array_shift($companies), "\n";
# adding item at the end
array_push($companies, 'ADOBE');
# adding item at the beginning
array_unshift($companies, 'NOVELL');
# ruby
companies = ['apple', 'microsoft', 'red hat', 'canonical']
puts companies.size # how many items?
puts companies.first # first item
puts companies.last # last item
puts companies.empty? # size > 0?
# sorting array
companies.sort!
# removing duplicate items
companies.uniq!
# applying a function
companies.map! { |company| company.upcase }
# reversing
companies.reverse!
# joining
puts companies.join(", ")
# slicing
puts companies[1..3].join(", ")
puts companies.slice(1, 3).join(", ")
# removing last item
puts companies.pop
# removing first item
puts companies.shift
# adding item at the end
companies.push 'ADOBE'
# adding item at the beginning
companies.unshift 'NOVELL'
Arrays associativos
No Ruby, os arrays associativos são definidos como Hash e tem sua sintaxe ligeiramente diferente. Vale lembrar que, ao iterar um hash, os valores apresentados geralmente não os mesmos da ordem de inserção.
# php
$companies = array(
'apple' => 'mac os x',
'microsoft' => 'windows vista',
'canonical' => 'ubuntu'
);
echo $companies['apple'], "\n";
# getting the keys
echo join(", ", array_keys($companies)), "\n";
# iterating through array
foreach ($companies as $company => $so) {
printf("%s: %s\n", $company, $so);
}
# removing a item
unset($companies['microsoft']);
# checking if array has a key
if (!array_key_exists('novell', $companies)) {
echo "Novell not found\n";
}
# ruby
companies = {
'apple' => 'mac os x',
'microsoft' => 'windows vista',
'canonical' => 'ubuntu'
}
puts companies['apple']
# getting the keys
puts companies.keys.join(", ")
# iterating through array
companies.each do |company, so|
puts "%s: %s" % [company, so]
end
# removing a item
companies.delete('microsoft')
# checking if array has a key
puts 'Novell not found' if not companies.key?('novell')
Arquivos e diretórios
Arquivos
Criar novo novo arquivo e adicionar conteúdo
# php
$file = fopen('newfile.txt', 'w+');
fwrite($file, str_repeat("i love php\n", 10));
fclose($file);
# ruby
file = File.new('newfile.txt', 'w+')
file << "i love ruby\n" * 10
file.close
Lendo arquivos
# php
$file = fopen('newfile.txt', 'r');
echo fwrite($file, ('newfile.txt')), "\n";
fclose($file);
# ruby
file = File.new('newfile.txt')
puts file.read
file.close
Iterando nas linhas do arquivo
# php
$lines = file('newfile.txt');
foreach ($lines as $num => $line) {
echo $num+1, ': ', $line;
}
# ruby
file = File.new('newfile.txt')
file.each_with_index do |line, num|
puts "%d: %s" % [num+1, line]
end
file.close
Outras funções
# php
# check if file exists
echo (int)file_exists('newfile.txt'), "\n";
# print file size in bytes
echo filesize('newfile.txt'), "\n";
# write permission?
echo (int)is_writable('newfile.txt'), "\n";
# read permission?
echo (int)is_readable('newfile.txt'), "\n";
# is file?
echo (int)is_file('newfile.txt'), "\n";
# remove file
unlink('newfile.txt');
# ruby
# check if file exists
puts File.exists?('newfile.txt')
# print file size in bytes
puts File.size('newfile.txt')
# write permission?
puts File.writable?('newfile.txt')
# read permission?
puts File.readable?('newfile.txt')
# is file?
puts File.file?('newfile.txt')
# remove file
File.unlink('newfile.txt')
Diretórios
# php
# creating new directory
mkdir('newdir');
# listing files
$dir = opendir("newdir");
while (false !== ($entry = readdir($dir))) {
echo $entry, "\n";
}
closedir($dir);
# directory?
echo (int)is_dir('newdir'), "\n";
# remove non-empty directory
# php have no such function
# check this link out for alternatives
# http://php.net/rmdir
# remove empty directory
rmdir('newdir');
# ruby
# creating new directory
dir = Dir.mkdir('newdir')
file = File.new('newdir/newfile.txt', 'w+')
# listing files
dir = Dir.new('newdir')
dir.entries.each do |entry|
puts entry
end
# directory?
puts File.directory?('newdir')
# remove non-empty directory
require 'fileutils'
FileUtils.rm_rf('newdir')
# remove empty directory
Dir.mkdir('newdir')
Dir.rmdir('newdir')
Classes
# php
class Vehicle {
# read/write attribute
public $name;
# private attribute
private $color;
# constructor
function __construct($name)
{
$this->name = $name;
}
# setter
function setColor($colorName)
{
$this->color = $colorName;
}
# getter
function getColor()
{
return $this->color;
}
# static
function getWheels()
{
return 0;
}
}
class Car extends Vehicle {
function __construct($name)
{
parent::__construct($name);
}
function getWheels()
{
return 4;
}
}
$car = new Car('Stilo');
echo $car->name, "\n"; # name attribute
echo get_class($car), "\n"; # object class
$car->setColor('graffiti');
echo $car->getColor(), "\n";
echo Car::getWheels(), "\n"; # static method
# ruby
class Vehicle
# read/write attribute
attr_accessor :name
# class variable
@@wheels = 0
# contructor
def initialize(name)
@name = name
end
# color getter
def color
@color
end
# color setter
def color=(color_name)
@color = color_name
end
def self.wheels
@@wheels
end
end
class Car < Vehicle
@@wheels = 4
def initialize(name)
super(name)
end
end
car = Car.new('Stilo')
puts car.name # name attribute
puts car.class # object class
car.color = 'yellow'
puts car.color
puts Car::wheels # class method (static method on PHP)
Lendo páginas da web (scraping)
Processando XML
# php
$curl = curl_init('http://del.icio.us/rss/fnando');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($curl);
$xml = new SimpleXMLElement($response);
foreach ($xml->item as $item) {
$title = $item->title;
$link = $item->link;
printf("%s\n%s\n\n", $title, $link);
}
# ruby
require 'net/http'
require 'uri'
require 'rexml/document'
url = URI.parse('http://del.icio.us/rss/fnando')
response = Net::HTTP.get(url)
xml = REXML::Document.new(response)
xml.root.elements.to_a('//item').each do |item|
title = item.elements['title'].text
link = item.elements['link'].text
puts "%s\n%s\n\n" % [title, link]
end
Processando HTML
# php
$curl = curl_init('http://www.google.com/trends/music');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($curl);
preg_match_all("/<a.*?href=\".*?&res=artist.*?>(.*?)<\/a>/sim", $response, $matches);
echo join("\n", array_unique($matches[1])), "\n";
require 'net/http'
require 'uri'
require 'rexml/document'
url = URI.parse('http://www.google.com/trends/music')
response = Net::HTTP.get(url)
regex = /<a.*?href=".*?&res=artist.*?>(.*?)<\/a>/sim
puts response.scan(regex).uniq.join("\n")
Se você acha que eu deveria ter abordado algum outro conjunto de funções, avise-me e atualizarei o artigo. Divirta-se!
Update: Adicionei estruturas de controle
- Permalink
- Trackback
- Feed dos comentários
- Ao som de: Hit The Lights – Bodybag

Comentários #
Excelente post Nando,
Como você falou, é mais fácil aprender uma nova linguagem comparando-a com outra. No meu caso que utilizo o PHP, e nunca lidei com o Ruby, este artigo foi uma ótima iniciativa.
Um abraço.
muito bom o artigo, é bem como voce disse..
é mais facil aprender uma linguagem comparando com uma que você ja domina.
parabéns
Legal a comparação. Pelo que percebi, o que muda é o Ruby é mais orientado a objeto que o Php. Mas como diria uma amigo meu: "o que muda é o nome das funções".
Pelo menos foi isso que percebi. Mas tenho que salientar que em alguns casos o Ruby ganha em simplicidade.
Excelente artigo…
Tava mesmo precisando de uma comparação…
Juro que era isso que eu estava procurando!
Grande abraço!
olá nando! Hoje mesmo estava falando para um colega de trabalho que programa em PHP sobre ruby, mas não tinha tantos argumentos (sou designer [o que um designer faz num blog de ruby???]) agora vou passar esse link pra ele!!
muito bom, como você falou, melhor aprender comparando com algo que a gente já conheça!!
abraço
Nando Perfeito, muito bom pra quem ta aprendendo Rails, parabéns
Muito bom mesmo!
Agradeço à vc pelos minutos e gastos escrevendo este post, assim até me animo a dar uma estudada em ruby, para depois ganhar conforto ao partir pro rails.
Abraço!
Belo post! Vamos ver se eu me animo a terminar meu texto sobre PHP e Lua :)
Fala Nando… gostei muito do post, Faz muito tempo que eu queria dar uma olhada em Ruby mas tava meio sem vontade sem tempo. =) Agora eu tenho uma duvida. O Ruby serve para internet também? Forte abraço.
Show de bola Ferdinando!
Já que a documentação do PHP é tão rica e a comunidade PHP é grande, esses exemplos são ótimos para pegar o "fio da meada" de uma linguagem pra outra!
PS: Precisa acertar o tabindex do "captcha" aqui embaixo. Um tab aqui nos comentários vai direto para o submit. =)
[]'s
Bem interessante.. não tinha visto ainda essa comparação.
Linguagens são linguagens.. sintaxes diferentes para a mesma lógica. E o Ruby tem uma sintaxe agradável. Só achei estranha a definição da classe, principalmente os atributos da classe.
Muito bom este post, ajuda bastante gente a começar a se aventurar com o RoR :D
Com a mesma idéia acho que o pessoal sente um pouco de falta de uma IDE para isto …
então comecei a escrever uma série de posts sobre IDEs para RoR (o primeiro é este sobre o RadRails http://www.urubatan.com.br/2007/08/05/ruby-on-rails-ide-war-1-aptana-rad-rails/ )
E se você se interessar, gostaria de deixar um convite também, para que você escreva um post descrevendo o seu ambiente de desenvolvimento …
Se quiser publicar aqui eu coloco um link la no meu blog, ou se quiser publicar la no meu blog mesmo sera muito bem vindo … )
Abraço
#12 Rodrigo: O que eu uso está aqui: http://simplesideias.com.br/tags/gedit ;)
"A maneira mais fácil de se aprender uma nova linguagem é comparando-a com uma linguagem que você já conhece."
Perfeito, excelente post! :)
ual…
fántastico.
De tempos em tempo você nos presenteia com posts como esse.
Nossa muito bom! Precisava disso mesmo.
Muito legal mesmo.
Nunca tinha visto ruby. Muito parecido com python hein.
Apesar de não ver necessidade de trocar php por ruby, ainda mais com agora a vinda do Zend Framework, estou confiante no PHP.
Mas uma coisa que com certeza o ruby ganha de php é na facilidade da sintaxe, coisinhas simples é muito mais facil de fazer. Que provavelmente puxou do python isso. hehe
Abraços
Muito bom mesmo, salvei nos delicious.
A muito já venho flertando com o ruby, mas estou adiando ainda… quando eu for começar a bricar com ror vou dar uma olhada aqui novamente. Parabens
[...] http://simplesideias.com.br/ruby-para-programadores-php [...]
[...] Simples Idéias. Por Nando Vieira. » Arquivo » Ruby para programadores PHP (tags: programming:ruby programming:php) [...]
[...] Ruby para Programadores PHP Setembro 10, 2007 at 8:01 pm | In Rapidinha, Dicas, ruby | Eis aqui um ótimo post para quem sabe PHP e está querendo aprender Ruby (como no meu caso), o autor do Post faz uma analogia entre as duas linguagens utilizando diversos recursos do PHP e implementando em Ruby, e da forma como foi escrito não tem como não aprender, para saber mais basta seguir o link. [...]
Parabéns!! Ótima iniciativa!
Parabéns Fernando,
Muito bom esse material.
Poxa legal!
Parabens!! era exatamente o q estava procurando!!!
muito bom mesmo!!!!!!
Excelente post.
A comparação foi muito bem conduzida por você, facilitou muito o meu aprendizado nesta nova linguagem que estou me aventurando. Durante as comparações acabei comparando alem do php com o Action Script, que no termo de OO está bem similar.
Grande abraço.
Ótimo post. Eu estava procurando exemplo de curl+xml e o achei.
Parabéns! =]
[...] dedicada ao Ruby on Rails, decidi que ao invés de começa nos principios do RoR (o Nando Viera do Simples Ideias já fez isso bem o bastante) vou iniciar com umas das primeiras peças que criei que podem ser [...]
Excelente texto gostei do unless do Ruby, mas por enquanto continuo no PHP.
Abraços
Deixe um comentário