28 de fevereiro de 2011

Ruby em 15 minutos

É, o mundo se move e nós sempre aprendemos linguagens novas.

Eis aqui mais um fast track. Agora, de Ruby.

Como esse fast track é destinado a programadores, muitos exemplos não têm explicação. Preste atenção aos detalhes e use o shell do Ruby (IRB) para testar os códigos abaixo. ;-)

Antes de começarmos, vamos a algumas definições da linguagem:
  1. Ruby é case sensitive. nome é diferente de Nome
  2. Ruby tem tipagem forte, mas dinâmica. Igual ao Python.
  3. Tudo é objeto, inclusive os tipos "primitivos" String, Integer, Float, Array, etc.
  4. Nem sempre os parênteses são necessários ao passar parâmetros para métodos.
  5. Métodos que terminam com um sinal de interrogação, normalmente retornam valor booleano.
  6. Métodos que terminam com um sinal de exclamação, normalmente modificam o objeto sobre o qual ele está agindo.
  7. Para blocos de código, tanto faz usar do...end ou as chaves.
  8. Variáveis de instância começam com @
  9. Variáveis de classe começam com @@
  10. Todos os testes booleanos retornam true, exceto false e nil. Isso significa que zero e string vazia retornam true!
Agora, mão na massa!

puts 'aspas simples ou duplas?'
puts "tanto faz"
nome = 'Maria'
puts "mas as aspas duplas mostram #{nome}"
# tipos e variaveis
nome = 'Maria'
idade = 34
eh_mulher = true
media_em_matematica = 8.5
cores = ['azul', 'preto', 'branco']
dados = {'nome' => 'Jose', 'endereco' => 'Rua 7 de setembro' }

a = 5
b = 10
a,b = b,a
puts 'a=' + a.to_s + ' b=' + b.to_s

a = '10'
puts a.to_i * 2
# if em uma linha só precisa do "then"
nome = 'maria'
if nome == 'maria' then puts 'mulher' end 
# entrada de dados, conversao e if com elsif + else
entrada = gets.chomp
n = entrada.to_i.abs

if n < 0
  puts 'nota invalida'
if n == 0
  puts 'zero?!'
elsif n > 0 and n < 5
  puts 'abaixo da media'
elseif n >= 5 and n < 10
  puts 'dentro da media'
  puts 'tirou 10!'
# unless é o contrário (else) do if
nome = 'maria'
unless nome == 'joao' then
  puts 'mulher'
# String
nome = 'Maria do Socorro'
puts nome.downcase
puts nome.upcase
puts nome.swapcase
puts nome.reverse

largura = 70
puts nome.center(largura)
puts nome.ljust(largura)
puts nome.rjust(largura)

puts nome.start_with?('Ma')
puts nome.end_with?('x')
puts nome.include?('Soco')

puts '-' * 70
puts 'Maria ' 'da ' 'Silva'
puts 'Maria ' + "da " + "Silva"
# Números
puts 5*2
puts 5+2
puts 5-2
puts 5**2
n = 5*2
puts 'o resultado: ' + n.to_s
puts 10.to_s
puts -5.abs
puts rand
puts rand(100)
if rand(100) != n then puts 'gerou diferente' end
if rand(100) > n then puts 'gerou maior' end
# Loops
3.times do |i|
  puts 'passei ' + i.to_s

1.upto(3) do |i| # tem também o downto
  puts i

for i in (1..3) do
  puts 'passei ' + i.to_s

i = 1
while i <= 3
  puts 'estou no ' + i.to_s
  i += 1

(1..3).each do |i|
  puts i

(1..3).each {
  puts i

('a'..'z').each do |letra|
  puts letra

i = 0
loop {
  i += 1
  puts i
  if i == 3 then

# cuidado!
i = 0
  i += 1
  puts i
end while i <= 3
# Arrays
cores = ['preto', 'branco', 'azul']
puts cores.join(', ')
puts cores.first
puts cores[0]
puts cores.last
puts cores[-1]
puts cores.length
puts cores.min
puts cores.max
puts cores.include?('amarelo')
cor1, cor2, cor3 = cores

grandes = cores.collect{ |cor| cor.upcase }
puts grandes

for item in cores
  puts 'a cor atual é ' + item

cores.each do |item|
  puts 'a cor atual é ' + item

cores.push 'cinza'
puts cores.length
puts cores

puts cores

outras_cores = cores.clone
# Hashes
dados = { 'nome' => 'maria', 'idade'=> 74 }
puts dados['nome']

mesmo = dados
mesmo['nome'] = 'Joana'
puts dados['nome']

outro = dados.clone
outro['nome'] = 'Marcos'
puts dados['nome']
puts outro['nome']

for k,v in dados
  puts "#{k} = #{v}"

dados.each_pair do |k, v|
  puts "#{k} = #{v}"

dados.each do |k,v|
  puts "#{k} = #{v}"

dados.each do |x|
  puts x

puts dados.has_key?('nome')
puts dados.has_value?('Fernando')
# Métodos
def oi pessoa # nao precisa dos parenteses! :-o
  puts 'Oi ' + pessoa
oi 'vinicius' # aqui também nao.

def soma (a, b)
  c = a + b # não precisa do return
total = soma(1,2)
puts total
# Inspecionando os tipos "primitivos"
puts String.instance_methods.sort
puts Integer.instance_methods.sort
puts Float.instance_methods.sort
puts Array.instance_methods.sort
puts Hash.instance_methods.sort
puts File.instance_methods.sort
# classes e objetos
class Pessoa
  def initialize (nome_parm) # esse é o constructor.
    @nome = nome_parm

  def eh_homem?
    homens = ['joao', 'fernando', 'vinicius', 'carlos']
    return (homens.include? @nome.downcase)

pai = Pessoa.new('Joao')
if pai.eh_homem?
  puts 'é o pai'
  puts 'humm...'

# attr_accessor age como uma property.
class Animal
  attr_accessor :nome # funciona como getter e setter.
  attr_reader :idade # getter.

  def initialize nome
    @nome = nome

  def idade=(idade) # setter personalizado.
    @idade = idade.abs

cao = Animal.new('Toto')
puts cao.nome
cao.nome = 'Petunia'
cao.idade = -5
puts cao.nome + ' tem ' + cao.idade.to_s + ' ano(s) de idade.'

9 de fevereiro de 2011

Run the ultra-marathon along with web2py

Runner athletes have big difference in their profiles.

Some of them explode in speed. They arrive super fast, but their bodies can’t support much time. They usually use the cutting edge technology in food, physical exercises and clothes with great aerodynamics. They are often the innovators. They must achieve quick results and stop early.

Their coleagues, long distance runners, need to prepare themselves to a more intense physical and emotional activity. The ultra-marathonists run for days, face cold, warm, sun, darkness, different heights, all in a single run. They need do feed themselves often and stop to stretching. Their shoes need to be extremelly comfortable: absorve impacts and protect from injuries.

Application developers must understand that long term customers want long term commitment. And long term plans. Your appointment doesn’t finish a few seconds away. Your are focused in a future objective. It’s a ultra-marathon, not a 100m running.

Technologies envolved must be safe, with continuation compromise. Very often we need to adjust things, we bring alternatives, but the big picture is already designed. We need to remind the rules, our competitors, renew our strengths. But it’s still the same running.

I want to clear out this way of thinking does not promote you to keep doing things the same way you always did. You need and must innovate in every single opportunity, but safely. Your choices need to be based on real indicators.

Maybe the more important choices, that will dictate if you will keep walking or will need to rewind are programing languages (business rules, automation scripts, templates, data manipulation), data base management systems and the framework will keep you appart from boring and difficult tasks to let you focus on your goal: your apps.

These points are often under attention, even for professional developers. I already faced people choose some language “because everybody I know is using it”, “because it’s the natural transition” ou “because we already know it”. If you do this way, wake up! These are important arguments, but they don’t have a solid background.

I met Java developers that had never heard about Python until they knew me. Visual Objects were “the natural transition” from Clipper to Windows, in early 90’s. I’ve worked in a place with a PHP “culture” because they had some sites written in it, but they didn’t know even why they chose PHP. Here in Brazil we hear often “when your only tool is a hammer, all your problems seem to be a nails”.

As a developer, your business core value is intellectual and the programming language expresses your app rules is too valuable to you. It will determine if that “bit of feature” to be fixed or implemented will be 1 hour or 3 days long.

Nowadays I am developing applications using web2py. Some characteristcs I voted pros are:
  1. It has official commitment with backwards compatibility. None compatibility was broken in 3 years. What I developed, keeps running.
  2. It is written in Python, to develop Python apps. A mature language, increasing its marketshare, used by big players worldwide. I can develop object oriented, or not. I can write administration or automation scripts, if I want.
  3. I can use Python to render my views. Using the same language, lesser is the learning curve.
  4. It’s self-contained. In other words, unzip and use. All dependencies are already there. This accelerates my deploying and configuration process. It comes with jquery, PDF generator, Ajax, etc.
  5. It’s open source.
  6. DAL (Data Abstraction Layer) may be decoupled. It means if I need to develop a module to work out of web I can still use the same data access language. In other words, DRY (Don’t Repeat Yourself).
  7. There’s a lot of free site templates ready to use, made from CSS Zen Garden and Free Templates.
  8. There’s a trully receptive and organized comunity, even in Brazil. (nice!)
If you plan see your applications lasting for years without the need to rewrite, choose your development environment with all this in mind.

Who stands and plans, reaches the ultra-marathon’s finish line.