nunojob:~ dscape/08$ echo The Black Sheep

Posts tagged ‘Ruby’

RSA Encrypt & Decrypt in ruby

Well I finished the encrypt with RSA on ruby some hours ago and felt like sharing :)

Case you feel like doing something back for me just download the latest release of my beta twitter client and send me some comments to my email. It’s pretty hard to test something when my environment is completely contaminated !

require 'openssl'
require 'Base64'

class Rudolph
  class Crypt
    def initialize data_path
      @data_path = data_path
      @private   = get_key 'id_rsa'
      @public    = get_key 'id_rsa.pub'
    end

    def encrypt_string message
      Base64::encode64(@public.public_encrypt(message)).rstrip
    end

    def decrypt_string message
      @private.private_decrypt Base64::decode64(message)
    end

    def self.generate_keys data_path
      rsa_path = File.join(data_path, 'rsa')
      privkey  = File.join(rsa_path, 'id_rsa')
      pubkey   = File.join(rsa_path, 'id_rsa.pub')
      unless File.exists?(privkey) || File.exists?(pubkey)
        keypair  = OpenSSL::PKey::RSA.generate(1024)
        Dir.mkdir(rsa_path) unless File.exist?(rsa_path)
        File.open(privkey, 'w') { |f| f.write keypair.to_pem } unless File.exists? privkey
        File.open(pubkey, 'w') { |f| f.write keypair.public_key.to_pem } unless File.exists? pubkey
      end
    end

    private
    def get_key filename
      OpenSSL::PKey::RSA.new File.read(File.join(@data_path, 'rsa', filename))
    end
  end
end

Rudolph – Yet another Twitter client

I felt like trying the Shoes framework. Here are the results so far. When I get some free time I’ll try to post some guidelines to do something like this.

Webpage: http://the-shoebox.org/apps/105

Github: http://github.com/dscape/rudolph

Open Source Online Testing System (OSOTS)

I simply can’t believe that I forgot to post this project in my blog. Anyway if you have to deploy a multiple choice test and you feel like messing arround with Ruby on Rails and DB2 here goes the link.

Open Source Online Testing System (OSOTS)

Cuidado com os tigres

Mais uma excelente talk do Steve Yegge.

Scala, now, is the tiger that’s going to kill Java. Because their [type-talisman] argument now has become a paradox, similar to the Paul Graham Blub Paradox thing, right? Because they’re like, “Well, we need static typing in order to engineer good systems. It’s simply not possible otherwise.”

The Scala people come in and they go: “Your type system suuuuuucks. It’s not sound. It’s not safe. It’s not complete. You’re casting your way around it. It doesn’t actually prevent this large class of bugs. How many times have you written catch (NullPointerException x) ... in Java? Our type system doesn’t allow [things like] that.”

Our type system does what you said your type system was doing.

So, therefore, you should be using it! ∴

And the Java people look at it and go: “Wehellll… (cough cough)… I mean, yeah, I mean… (*ahem*)(running finger under collar, as if sweating profusely) They say, “Welllll… you know… it’s awfully… cummmmmbersome… I…”

“We can actually get around the problems in practice that you guys say your type system is solving through Good Engineering Practices.”

(laughter begins to grow)

HA!!! (I point accusingly at the audience, and there’s more laughter)

Yeah.

So Scala is creating a real problem for [Java's] static typing camp now. Because their last little bastion of why they’re using it, the whole tigers argument, they’re like, “Ah, well… we… we keep shotguns in our house.” [This is what they've been reduced to.]

OK? Yeeeeahhhh…

So back to dynamic languages!

Ruby Ruby Ruby Ruby

Parece que fui ao rock in rio ver kaiser chiefs (e fui).

Estava para aqui a brincar ao ruby e assim do nada encontro-me a chamar métodos dinamicamente (ruby as a meta-language) que devolviam strings. Tudo bem até chegar a um que devolvia integer e eis que aparece aquele erro:

NoMethodError in SearchController#search

undefined method `include?’ for 7:Fixnum

Que fazer? Mudar aquela linha de código por um if e contemplar as duas possibilidades? Ou simplesmente alterar o Fixnum e ensinar-lhe o que eu esperava que o include? fizesse? Eu fui pela segunda opção:


class Fixnum
  def include?(object)
    to_i == object.to_i
  end
end

Em linguagens assim dá gosto trabalhar!

Wouldn’t ANTLR be better if written in a dynamic language?

I think making a tool like ANTLR is a non-dynamic language is a shot in the foot!

It just makes sense to use dynamic languages to create meta-language tools. Would facilitate the work of the developer and of the ones writing grammars taking away all that java trash that helps in nothing to make out stuff work. ANTLR is great, but all the negative aspects (from end-user point of view) arise from the fact of having all that unnecessary information and needing to declare types and other stuff that ARE NOT NATURAL for a grammar to have. And the way it’s implemented in Java is just a way of copying the way (bad) dynamic languages work.

grammar Expr; 

options {
  output = AST;
  ASTLabelType = CommonTree;
} 

prog
     : ( stat
         { System.out.println( $stat.tree.toStringTree() ); }
       )+
     ;

stat
     : expr NEWLINE -> expr
     | ID '=' expr NEWLINE -> ^('=' ID expr)
     | NEWLINE ->
     ; 

expr
     : multExpr ( ( '+'^ | '-'^ ) multExpr )*
     ;

multExpr
     : atom ( '*'^ atom )*
     ;

atom
     : INT
     | ID
     | '('! expr ')'!
; 

ID
     : ( 'a'..'z' | 'A'..'Z' )+
     ;

INT
     : '0'..'9'+
     ; 

NEWLINE
     : '\r'? '\n'
     ; 

WS
     : ( ' ' | '\t' | '\n' | '\r' )+
       { $channel=HIDDEN; }
     ;
grammar Expr; 

options {
  output = AST;
} 

prog
     : ( stat
         { puts $stat.to_tree }
       )+
     ;

stat
     : expr NEWLINE
     | ID '=' expr NEWLINE -> ^ // mark the root somehow
     | NEWLINE
     ; 

expr
     : multExpr ( ( '+'^ | '-'^ ) multExpr )*
     ;

multExpr
     : atom ( '*'^ atom )*
     ;

atom
     : INT
     | ID
     | '('! expr ')'!
; 

ID
     : ( 'a'..'z' | 'A'..'Z' )+
     ;

INT
     : '0'..'9'+
     ; 

NEWLINE
     : '\r'? '\n'
     ; 

WS
     : ( ' ' | '\t' | '\n' | '\r' )+
       { skip }
     ;

Just wish I had the time to implement it in Ruby and prove my point! Maybe in the masters thesis..

By the way, the ANTLR Book is great. If you want to learn about grammars and creating DSL’s you will love it. But be advised, you’ll hate the java trash that comes with it.

By the way Google changed their icon.

But once again, who gives a fuck? I sure don’t.

Information Retrieval using the Boolean Model in Ruby on Rails

famfamfam flag iconset yaml representation on ruby

First download the flags from famfamfam into a folder called flags (pngs only,
no subfolders!).

Now in the bash:

cd flags
wget http://www.iso.org/iso/iso3166_en_code_lists.txt
ls > file.txt
irb

Now your on the interactive ruby shell (irb).

# If you want to use this as a script just copy 
# the bash lines and put them as
# system 'cd flags'
# system 'wget ...' and so on

# We start treating the output from the ls
# open the ls output
f = File.new 'file.txt'                            
# place the file in lines
lines = f.readlines                                
# map those who have 2 digits codes
lines = lines.select { |line| line.size == 7 }    
# get the 2 digits 
lines = lines.map { |line| line[0..1] }            
f.close

# Then the iso file
# open the iso file
f = File.new 'iso3166_en_code_lists.txt' 
# get rid of the notes          
f.readline                                         
# place the file in iso
iso = f.readlines                                  
# create a new hash
hashed_iso = {}                                    
# select non empty lines
iso.select { |a| !a.rstrip.empty? }.map do |b|
  # remove the whitespaces and split in ';'     
  aux = b.rstrip.split ';'     
  # place info in the hash                    
  hashed_iso[aux[1].downcase] = aux[0].capitalize  
end
f.close

# Now we cross information giving more 
# importance to what's in the iso.
iso_famfamfam = hashed_iso.select {
  # select those who have flags in famfamfam
  |k,v| lines.member? k                            
}.sort_by {
  # sort them by the name the user will see
  |pair| pair[1]                                   
}

# Now we create the contents to store in the yaml file
# create the yaml first line
yaml_lines = "hash: \n"                           
iso_famfamfam.each do |pair|
  # for each pair, create the yaml
  # representation and put in yaml_lines
  yaml_lines < < '  ' + pair[0] + ': ' 
                         + pair[1] + "\n"    
end 

yaml_lines &lt;&lt; "array: ---\n"

iso_famfamfam.each do |pair|
  yaml_lines << '- - ' + pair[0] + "\n  - " 
                            + pair[1] + "\n" 
end 

# put it in a file
f = File.new 'flags.yml', 'w'
f.write yaml_lines
f.close

#sample for loading the yaml into ruby
f = File.new 'flags.yml'
fy = YAML.load f

Now you have your yaml representation of the flags. Do what you please. Personally I’m going to use the file to load it to Ruby when my Ruby on Rails app starts and use it as part of the registration system in the

Functional vs Imperative: Round 1

Imperative in python
Functional on a object oriented flavor in ruby

Note: You can do the opposite, ruby in imperative and python in functional (I’m guessing on the python part, but it’s probably true)

# choose all values from a list that are not in a matrix

# imperative in python
res = []

for value in list:
  present = False
  for mlist in matrix:
    if value in mlist:
      present = True
      break
   if not present:
     res.append(value)
# functional in ruby
res = list.select { |value| !matrix.flatten.member? value }

# restrict the matrix to values in list

# imperative strikes back
res = []

for mlist in matrix:
  current_mlist = mlist[:]
  for mvalue in mlist:
    if mvalue not in list:
      current_mlist.remove(mvalue)
  res.append(current_mlist)
# functional responds
res = matrix.map do |mlist| 
  mlist.select { |mvalue| list.member? mvalue } 
end

ROTD: Having fun with Ruby sort and sort_by methods

Simple sorting.

First comes a demonstration of the most common error :P
Then a simple sort
After that comes a first sort_by
And then a complete sort_by (sorted first by fname and then by lname).

>> h = [{'fname' => 'Nuno', 'lname' => 'Job'},
  {'fname' => 'Nuno', 'lname' => 'Fonseca'},
  {'fname' => 'Catarina', 'lname' => 'Pinto'},
  {'fname' => 'Nuno', 'lname' => 'Pinto'},
  {'fname' => 'Nuno', 'lname' => 'Antunes'}
]
>> h.sort
NoMethodError: undefined method '< =>' for 
{"lname"=>"Job", "fname"=>"Nuno"}:Hash
from (irb):35:in `sort'
from (irb):35
from :0
>> h.sort{|a,b| a['fname'] < => b['fname']}
=> [{"lname"=>"Pinto", "fname"=>"Catarina"},
{"lname"=>"Job", "fname"=>"Nuno"},
{"lname"=>"Fonseca", "fname"=>"Nuno"},
{"lname"=>"Pinto", "fname"=>"Nuno"},
{"lname"=>"Antunes", "fname"=>"Nuno"}]
>> h.sort_by{|p| p['fname']}
=> [{"lname"=>"Pinto", "fname"=>"Catarina"},
{"lname"=>"Job", "fname"=>"Nuno"},
{"lname"=>"Fonseca", "fname"=>"Nuno"},
{"lname"=>"Pinto", "fname"=>"Nuno"},
{"lname"=>"Antunes", "fname"=>"Nuno"}]
>> h.sort_by{|p| [p['fname'], p['lname']]}
=> [{"lname"=>"Pinto", "fname"=>"Catarina"},
{"lname"=>"Antunes", "fname"=>"Nuno"},
{"lname"=>"Fonseca", "fname"=>"Nuno"},
{"lname"=>"Job", "fname"=>"Nuno"},
{"lname"=>"Pinto", "fname"=>"Nuno"}]

Haskell $

Note: I know you will look away as soon as you see f x. Please don’t. You can see some interesting things in this post.

I was on the train with João and I was delighted to see my old friend $. I also miss composite (.) but $ is really the coolest shortcut Haskell gives a developer. So what is $?

It’s defined as:

f ($) x = f x

What does it does?

Prelude> let f x = map (succ) $ filter ( < 5 ) x
Prelude> f [4,5,7]
[5]
Prelude> let f  = zipWith ($)
Prelude> f [succ,id] [5,4]
[6,4]

Ulisses gave me the weird example. The first one was created by myself. In the first one we filter a list for numbers that are inferior to five and then we apply succ function to it. That is, we add one. :P Without $ we would have

Prelude> let f x = map (succ) (filter ( < 5 ) x)
Prelude> f [4,5,7]
[5]

So we got the parenthesis off and that always great to help make the code more readable. At least I simply love this symbol. Ulisses sample is quite more complex. First off all because it is in point-free/point-less notation. zipWith is a function that receives two lists and applies then function provided pair by pair. Like if I want to add [1,2,3] and [3,2,1] I can:

Prelude> zipWith (+) [1,2,3] [3,2,1]
[4,4,4]

Ain’t it cool? So in this function we simply apply function that goes in the first list (id and succ) to the numbers in the second. Looks easy like this doesn’t it? ;) If it doesn’t just to read it and digest it and you’ll figure it out easily.

Let code the same samples in Ruby. Unfortunately zipWith (should I commit it? :P) doesn’t exist in ruby I’ll have to work with another sample using plain zip (it’s the same as zipWith (\a b -> [a]++[b])).

irb(main):001:0> [1,2,3].zip([3,2,1])
=> [[1, 3], [2, 2], [3, 1]]

Well ruby handles this pretty well without $. We just need to do:

irb(main):002:0> [1,2,3].zip [3,2,1]

Because it’s object oriented this kind of issues don’t exist in Ruby. There are no expressions with large number of parenthesis as well. despite this I must agree that the Haskell version is far more readable than the ruby one:

irb(main):003:0> [4,5,7].select { 
  |i| i < 5 
}.map { |i| i.succ }
=> [5]

But I still miss $.I miss coding in Haskell. It’s just plain fun.

I hope that I have helped you see why languages like Haskell and Scheme do matter, and others like Python and Ruby can be both useful and fun to work with!

DB2 Rocks

qs = Question.find_by_sql 
"select X.* from ots_schema.questions," +
  "XMLTABLE (\'$d/question\' passing document as \"d\" " + 
    "COLUMNS question_text VARCHAR(200)" + 
    "PATH \'question_text\') as X"
qs.first.question_text.lstrip
=> "Which of the following is the correct syntax to set the DB2COMM variable to TCPIP?\n  "

If DB2 was had a good DB2 driver and a ActivePureXML (or something adapter) it would so f*ckin rock. Just look at the sample. And the dynamic nature of ruby would enable the flexibility of xml documents.

Please IBM please. DB2 for mac and decent support on Ruby. Don’t make me write things like this no more:

# Once again fixing IBM_DB bugs the ugly way
# with_scope anyone?
add_index :'ots_schema.users', :login

or

t.column :document, :xml

Google reinvents the wheel

About porting Ruby on Rails to Javascript:

In an effort to increase developer productivity at Google, Steve tried to convince the company to adopt Rails (and consequently Ruby) as a programming language. When that fell on deaf ears (Google really does not want to increase the number of languages that must be supported by their infrastructure), Steve decided to do what any other frustrated programmer would do: he ported Rails to JavaScript. Line by line. In 6 months. Working 2000 hours. Steve is a coding stud.

From: Steve Yegge ported Rails to JavaScript

In this six months Steve could have contributed to the rails core and improved the framework to a great extent. If he found security issues like the article refers than he should have fixed them in rails. I cannot even begin to understand why he didn’t by the way. Or at least reported them.

My conclusion of seeing that google allowed a employee to waste 6 months of work because they don’t want to increase the number of languages that must be supported by their infrastructure is that Google is Dumb.

Steve seems like a smart guy so if I was told to rewrite Ruby on Rails by an employer I cannot understand why he didn’t – at the very least – refused to do so and pointed out how stupid it was to reinvent the wheel. I simply hate javascript and love ruby. I think javascript is the worst thing there is in the internet. That’s one of the reasons I decided to take a chance on XForms. Well but that’s a personal opinion and has nothing to do with the case!
The question is:

So will this bring something new to the web?

Yes! But it’s not that this wheel is great and the other was flat. It can bring something but just because Google has the power to do that, in any language they decide to use. They have the man power to go beyond what rails offer.

But does this make the decision less dumb?

No. They could do it in rails and improve a great open source product.
Or is it that hard for engineers at google to learn a new language??

Valid and Well-formed XML Documents in Ruby on Rails

If your working with DB2 on Rails you probably need to check if the xml document is – at least – well formed.

I found a neat plugin called validates-xml that uses REXML to see if documents are well formed.

To install it simply

svn co http://validates-xml.googlecode.com/svn/trunk/ validates-xml-read-only

And copy that folder to vendor/plugins.

You can easily integrate schema validation with a validates_xml_with_schema method. But you should use REXML as it cames with the standard ruby bundle since version 1.8.

To use it simply restart your server and

validates_xml :xmldocument

That’s it!

Yet Another Ruby on Rails Web Application – Teaser

Integração entre RSpec & TextMate

Como já disse anteriormente ando a trabalhar no CouchDB-Ruby driver. Como a coisa tem o seu nível de exigência decidi usar rspec, algo que já andava para fazer a algum tempo, de forma a melhorar a testagem do software que produzo e reduzir o tempo de implementação. Já agora aproveito para sugerir o ZenTest a quem quiser que o rspec corra em background.

Continuando: rspec é uma forma descritiva – tipo cenários em Use Case – para descrever os nossos testes. Em Ruby claro, dai o R :P

O resultado final fica assim. É catita e prático, já que evita mais uma ida a consola para escrever ‘spec filename.rb’! E é bastante parecida com a linguagem natural. Por exemplo – um dos meus primeiros testes é:

it "should connect to server and return a Server object" do
  CouchDB.connect(HOST, PORT).should 
    be_kind_of(CouchDB::Server)
end

Não fiz commit de nada porque a implementaçao anterior do CouchDB-Ruby com JSON não está completa. Portanto não vale a pena ir espreitar que não está nada lá! Em breve, espero eu, podem ver os testes completos online.

De qualquer forma se estiverem interessados em experimentar o rspec basta:

  • Instalar o rspec
    sudo gem install rspec
  • Descobrir o path onde está o ruby e o rspec. Estes comandos são capazes de ajudar:
    which ruby
    gem environment
  • Com os meus paths basta correr:
    export TM_RUBY=/usr/bin/ruby
    export TM_RSPEC_HOME=/Library/Ruby/Gems/1.8/gems/rspec-1.1.3
    cd ~/Library/Application\ Support/TextMate/Bundles/
    svn co svn://rubyforge.org/var/svn/rspec/trunk/RSpec.tmbundle
    
  • Como o (meu) terminal não gosta de exports. Caso não funcione façam:
    echo TM_RUBY=/usr/bin/ruby >> ~/.profile
    echo TM_RSPEC_HOME=/Library/Ruby/Gems/1.8/gems/rspec-1.1.3 &gt;&gt; ~/.profile
    
  • Actualizar os Bundles do TextMate
    Bundles > Bundle Editor > Reload Bundles

E pronto! Caso surjam dúvidas podem sempre consultar a documentação oficial do bundle rspec para TextMate. Que comece a diversão! Bem vá diversão é exagerar mas com rspec é pelo menos uma experiência mais agradável que o habitual quando se fala de testes.

CouchDB & Um Novo Semestre!

Bem todos os semestres faço um plano de acção do que vou fazer para além de o que é espectável de mim – ir as aulas, fazer os trabalhos, passar nos exames e ler pelo menos um livro de informática – de escolha livre – por mês.

Acredito na valorização pessoal e gosto muito de aprender coisas novas. E acredito que não existe melhor forma de o fazer que com projectos práticos!

Algumas das novidades do último semestre foram ter entrado no centro de apoio ao open-source do departamento de informática, ser eleito IBM DB2 Student Ambassador e ter entrado na melhor rede de bloggers de informática de portugal – prt.sc. Como projecto pessoal escolhi aprender – por sugestão do Ulisses CostaRuby & Ruby on Rails.

Dito isto resta uma dúvida: O que aprender este semestre?

Tenho que confessar que ando nas nuvens por terem aceite a minha colaboração no projecto CouchDB do rubyforge.

Como devem saber CouchDB é uma base de dados criada pelo Damien Katz (que trabalha agora na IBM), não relacional, desenvolvida em erlang que tem como objectivo guardar documentos e é RESTful. Os conceitos são excelentes e a forma de abordar o fault-tolerance e problemas de carga são daqueles conceitos que nos deixam a babar mortinhos por experimentar o brinquedo novo. Mas não se fica por aqui. Aconselho a lerem a wiki para terem uma noção do que é – e o que não é – o CouchDB. Só não gosto muito do facto de estar tão ligado a javascript e JSON – o primeiro porque nunca gostei muito de javascript e o segundo porque preferia yaml. Mas vá antes JSON que XML!

Outros tópicos que andam por aqui a passear – sendo que aqui é a minha cabeça – é a vontade de aprender um mínimo de Erlang e continuar o estudo de DB2 para tirar a certificação. Espero que quando acabar este semestre possa olhar para trás e sentir a mesma satisfação que sinto pelo semestre que já passou.

METS Standard with IBM DB2 Express C using XForms as user-interface and Ruby on Rails as a Rest Web-services

HIGH QUALITY VERSION DOWNLOAD HERE

Well, here is the long promised screen-cast. The amount of topics covered is simply huge. To get you ready for the screen-cast I prepared some other more introductory screen-cast as well as some articles on these subjects. I’m sorry that I don’t have the time to document the REST, but I really advice to invest some time learning it as it’s a very pragmatic way of delivering high quality web services.

I strongly advice you to download this screen-cast from rapidshare as both Youtube and Google Videos quality is really awful. You can download it from here.

This work was really fun to do. So I hope to have the opportunity to develop it further and manage nested rest routes like /mets/1/agents to return the agents of the first submission information package (sip) using some cool DB2 pureXML features. I really feel that with a good plugin to help users take full advantage of DB2 pureXML features and a little of imagination this web-service could be of some use.

I also expect to complete the xforms model as it is not indexing a fileptr to each category when such is selected. I hope to implement this soon enough.

Here are the associated resources I developed:

And here are the other two screencasts I produced to introduce you to XForms and METS:

I also advice you to take a look at this articles. All of them where very helpful to my work.

XmlSimple?

>> xml_plain = %q(<p>Just a <strong>p</strong> on bold</p>)
=> "<p>Just a <strong>p</strong> on bold</p>"
>> xml_hash = XmlSimple.xml_in xml_plain,
  'ForceArray' => true
=> {"strong"=>["p"], "content"=>["Just a ", " on bold"]}
>> xml_plain2 = XmlSimple.xml_out xml_hash, 
  'RootName' => 'p'
=> "<p>\n  <strong>p</strong>\n  <content>Just a </content>\n  <content> on bold</content>\n</p>\n"

Não querendo ser malvado com quem fez esta biblioteca acho que o mínimo expectável para uma operação de marshall/unmarshall é que seja reflexiva. Lá vou eu ler documentação para descobrir como se ensina o XMLSimple – nome curioso não é? – a ser o que nunca deveria deixar de ser. Reflexivo.

Já agora se alguém já programou web services em rails e sabe como transformar os params em xml de uma forma melhor, let me know!

Primeiro contacto com programação por parte dos alunos do ensino superior

Qual deve ser a linguagem de programação que serve de introdução ao seu curso superior de informática? Para mim a resposta não podia ser mais evidente: Haskell.

Pelo que sei no ISEP a primeira coisa que se aprende é Java, o que acho chocante. Afinal o paradigma de programação orientada aos objectos é vastíssimo e ensinar alguém a programar em Java sem estes conhecimentos por trás parece-me de uma irresponsabilidade incrível. Isto após uma reestruturação que ocorreu o ano passado! Pode-se alegar que o ISEP tenta formar profissionais que sejam absorvidos o mais rapidamente possível pelas empresas, que não se pretende formar investigadores. Mas, na minha opinião pessoal, existem coisas que são base para um licenciado em informática. Têm que conhecer os paradigmas de programação que existem pelas valias que eles oferecem e não pelo facto da sua sintaxe ser mais ou menos acessível. Como me parece evidente que qualquer informático deve saber estruturas de dados e algoritmia. São as ferramentas base com que trabalhamos diariamente e por muito que as empresas queiram monos lá a trabalhar a “chapar” código têm que existir algo que diferencie esse mono de um pedreiro. Senão para que o canudo?

Mas e porque Haskell?

  1. É uma linguagem funcional. Os problemas são entendidos como problemas matemáticos, o que permite aos alunos quebrar com a pre-formatada ideia que programar é deve ser seguindo o paradigma imperativo.
  2. A maneira de pensar nesta linguagem é diferente. Dijkstra disse que “It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.”. Aposto que ele diria o oposto sobre Haskell. É difícil ensinar mal alunos que começam por aprender/gostar de Haskell.
  3. Ao aprender os vários paradigmas o aluno torna-se mais versátil. Começando por Haskell certamente que não vai ver todos os problemas de uma forma imperativa. Esta forma diferente de pensar vai-lhe permitir, no futuro, a mais valia de saber escolher o método mais apropriado para resolver um problema que se depare no futuro. Pode na altura não usar Haskell mas vai-se lembrar dos mecanismos que aprendeu e da forma, correcta, que aprendeu para resolver problemas.
  4. As outras vantagens do Haskell: Esquema de recursividade extremamente simples, Strongly Typed, Lazy Evaluation, Elegância do código.

Atrevo-me até a dizer que podem dizer mal do Haskell em tudo que quiserem menos que é mau como ferramenta de ensino. Para isso, é simplesmente divinal.

Se quiserem ver uma melhor resposta a esta pergunta Why Haskell podem ler este artigo no Good Math, Bad Math. E caso queiram espreitar um pouco de código podem visitar (e rir-se um bocado com) este The Evolution of a Haskell Programmer.

Devolvam as passwords aos vossos utilizadores com Ruby on Rails 2.0

Uma coisa que me chateia imenso nas webapplications de trazer por casa – traduzindo aquelas que são feitas por colegas meus ou por outros amadores pela web fora – é o facto de guardarem quase sempre as passwords na base de dados em plaintext. Acho que não tem o direito de saber a password que uso, nem que a use exclusivamente nesse site (como é o caso)

Assim, se quem fez a aplicação for mal intencionado, pode simplesmente obter a vossa password escrevendo

select * from users where user.username = 'nick'

Mas mesmo que não sejam mal intencionados, outra pessoa pode aceder a base de dados. Ou podem simplesmente não se ter protegido contra sql injection. Há um milhão de razões pelas quais nunca se deve guardar as password em plaintext, sendo que a principal deles é o facto da password não ser vossa. É do utilizador. E isso faz toda a diferença! Não acreditam em mim certo? Estou a exagerar.

Convido-os a visitar esta página

Agora procurem por ‘qualquer_coisa. O resultado é

  • Pesquisa por “\’qualquer_coisa”:

Este \’ é importantíssimo pois significa que a página se esta a proteger contra ataques de sql injection. Caso contrario um hacker podia, com alguma sorte, obter informação privilegiada que estava contida nessa base de dados.

Mas ninguém faz um erro destes, certo? Errado. Vamos ao google e procurem php em páginas de Portugal. O sexto resultado, e único que testei, é a associação nacional de farmácias. Se procurarem por ‘qualquer_coisa o resultado é um não tão surpreendente erro. Isto é um exemplo de milhares, alguns dos quais onde vocês inserem as vossa password (e sabe-se lá o que mais) diariamente. Não se sentiam melhor se soubessem que nessa base de dados não está a vossa password?

Mas voltando ao assunto, a táctica que vou usar consiste em usar um algoritmo de one way hash chamado SHA. O utilizador, quando se regista no site, insere a sua password. Esta é processada (num processo que se chama de digest) para uma hash que contém não a password mas sim a encriptação dessa password em SHA. Como SHA é um algoritmo de one-way-hash, é fácil obter a hash única para qualquer palavra mas quase impossível de decifrar no sentido inverso. Para ser suficiente, mas não é.

Comecemos por ir para a consola do rails. Entrem no terminal e naveguem até onde tem a vossa Ruby on Rails web application. Agora escrevam.

./script/console

Quando lá estiverem podem verificar que aplicando este algoritmo a palavra porto obtemos sempre a mesma resposta.

>> password = 'porto'
=> "porto"
>> Digest::SHA256.hexdigest(password)
=> "01735c5ff1608734e4c38449a00b74bb9a8d5423ed548238da70178e9e803483"
>> Digest::SHA256.hexdigest(password)
=> "01735c5ff1608734e4c38449a00b74bb9a8d5423ed548238da70178e9e803483"

Não sei se repararam mas o nosso utilizador usa uma palavra pass muito fraca. Isto vai fazer a diferença, por o hacker pode obter a password facilmente se tiver a hash.

Como? Sim eu disse que era muito difícil crackar o SHA, alias não conheço ninguém que o tenha feito. Ninguém conhece :P

Mas o hacker pode pegar numa lista de palavras comuns nas passwords e, para cada uma das palavras associar a hash correspondente. Agora se tiver a vossa hash pode comparar com o dicionário que criou descobrir algumas das passwords da base de dados, aquelas que estavam na lista de palavras comuns.

Para resolver este problema usamos um salt. Um salt é também uma palavra (como a vossa password) que sera usada para evitar esta técnica. é mais simples mostrar que explicar, e por isso mesmo:

>> password = 'porto'
salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
>> salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
=> "19L6gVcD"
>> salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
=> "CqEVe632"
>> password = 'porto'
=> "porto"
>> Digest::SHA256.hexdigest(password + salt)
=> "c017e1c49096149097050c76f0406dce9245058e0d..."

De certeza que o hacker não vai procurar pela string portoCqEVe632 e, portanto, os nossos utilizadores estão seguros. Caso queiram saber um pouco mais sobre o que se passa no criação do salt, e que é aquele pack(‘m’) peçam nos comentários e eu escrevo um artigo sobre isso. Senão nunca mais saio daqui! :P.

Agora surge a pergunta, como usar esta informação em rails. Simples.

Vamos começar por criar um projecto:

rails secureusers && cd secureusers

Agora precisamos de criar o modelo de utilizador

./script/generate model User username:string \
  password_hash:string password_salt:string
rake db:migrate

Abram o vosso User.rb model, apaguem o que lá tem, e insiram o seguinte código

require 'digest/sha2'
class User < ActiveRecord::Base
# usei o attr_accessible em vez do
# attr_protected :password_hash, :password_salt
# porque é boa prática em Rails usar o enabled para 
# os campos acessíveis e não o contrário.
#
# Imaginem que tinham um campo isAdmin e se 
# esqueciam de por no protected.
# Ao dizerem que enabled só o :username impedem 
# o acesso a todo e qualquer outro campo,
# excepto aqueles que foram explicitamente 
# escolhidos por vocês.
  attr_accessible :username
  attr_accessor :password

  def before_save
    unless password.blank?
      salt = [Array.new(6){rand(256).chr}.join].pack("m").chomp
      self.password_salt, self.password_hash = salt,
      Digest::SHA256.hexdigest(password + salt)
    end
  end

  def self.authenticate(username, password)
    user = User.find :first,
        :conditions => ['username = ?', username])
      if user.blank?
        raise "O utilizador não existe"
      elsif Digest::SHA256.hexdigest(password + user.password_salt) != user.password_hash
        raise "A autenticação falhou"
      else
        user
      end
  end
end

Usei o attr_accessible em vez do protected porque considero esta uma boa practica. Prefiro dizer quais os campos acessíveis que quais os que se deve proteger. Assim não corro o risco de me esquecer de proteger algum campo. E os que são para ver nota-se bem quando faltam :P Podem ler mais sobre isto aqui.

Depois de toda esta explicação o código deve ser muito facil de entender. Até para quem não sabe Ruby. Vamos testar?

>> nuno = User.new
=> #<user id: nil,
  username: nil,
  password_hash: nil,
  password_salt: nil,
  created_at: nil,
  updated_at: nil>
>> nuno.username = 'nuno'
=> "nuno"
>> nuno.password = 'porto'
=> "porto"
>> nuno.save
=> true
>> nuno
=> #</user><user id: 1, 
  username: "nuno",
  password_hash: "c490ea11d96be24ece2ca0dba11d84fc9b...",
  password_salt: "V+b7Sqjh",
  created_at: "2008-02-12 19:28:54",
  updated_at: "2008-02-12 19:28:54">

E agora autenticar:

User.authenticate 'nuno', 'porto'
=> #</user><user id: 1, 
  username: "nuno",
  password_hash: "c490ea11d96be24ece2ca0dba11d84fc9b...",
  password_salt: "V+b7Sqjh",
  created_at: "2008-02-12 19:28:54",
  updated_at: "2008-02-12 19:28:54">

Fixe. É so por no session[:user] ;) Para finalizar aconselho-vos vivamente a suportarem open-id para o processo de autenticação dos utilizadores. Existem plugins muito bons que o fazem, e podem ler mais sobre open-id no seu fantástico guia supersónico.

e-archia.net

Bem a minha primeira aventura em rails chegou a metade. Quem estiver interessado em ver as sources, pode sacar este não-tão-pequeno ficheiro. Senão fica aqui a screenshot. O site não está online porque eu, com a pressa, não tenho a certeza ser fiz escapeHTML ao texto que vem da base de dados. Ficam as screenshots:

Working different models in the same form on Ruby on Rails

Well it’s been a heck of a week, loving somethings on rails and hating others :P

Anyway I had a problem with working with different models on a form. If you are having the same kind of issues I’ll give you some pointers:

My notes file is so big I think I’ll never solve all those issues. *g* Anyway another pointer I can give you is to check out haml. I didn’t used it but it sure is simpler than html.

Random in Ruby on Rails

So your doing a find on your model and you want a random instance. I didn’t find a method to do this so I decided to make my own.

In this case I wanted a random quote. So after generating the model all I had to do was:

def self.random
  Quote.find_by_id rand(Quote.count) + 1
end

And now you can simply call your random quotes in any controller action you desire. Just

@rquote = Quote.random

If this is the lamest ruby ever please feel free to give me some feedback :) I will be delighted to learn a different way!

[EDIT: Discussion about this at Rails Core]

This version of RMagick was created to run with ImageMagick 6.3.3 but ImageMagick 6.3.8 is in use

A paciencia tem os seus limites e vou dormir. Se entretanto alguém descobrir a solução para isto peço-lhe o favor de me deixar nos comentários.

Crescimento do emprego em Ruby

As coisas em Portugal costumam demorar a chegar ao ponto que estão nos states. Basta ver que a maioria das propostas que vejo por cá são em Visual Basic (hein?). De qualquer forma convido-os a ver estes gráficos a tirarem as vossas próprias ilações:

Ruby, Java ou C#?

Ruby on Rails, PHP ou ASP.NET?

Será que alguma vez as empresas de portugal iram estar um passo a frente em vez de vinte passos atrás? Não me parece mas, uma pessoa pode sempre sonhar!

Skitchcast: Ruby Gems is now on v1.0

Here how to update your gem to 1.0 and RoR to 2.0.2

Imagem do dia

Atenção: Esta ilustração mostra como limpar as preferências do TextMate. É apenas um devaneio geek, que mostra como se pode complicar até a mais simples das coisas. A próxima versão será em base-64, para piorar ainda mais o cenário. Contudo quero deixar claro que o uso ilícito de software proprietário é crime. Se através deste exemplo descobrirem como se faz e o fizerem estão a vossa própria responsabilidade.

From Ubuntu/Windows to Mac OS-X Leopard

I just got my first brand new MacBook and, as one would expect, some problems emerged by leaving my usual OS combo (Ubuntu/Windows) for Mac OS X Leopard. I’m still undecided whether to install Ubuntu or use VMWare Fusion to use Linux. As for Microsoft Windows as long as I don’t need to use .NET I don’t think I’ll install it. Not even with the free licenses Microsoft provides University of Minho students.

First I had to decide what to install:

The question you are probably asking is why Firefox instead of Safari!? Because the damn unsafe add-on for del.icio.us is just that: del.icio.us! I just can’t live without it. Maybe if the guys over there worked the basics of security we could say that it’s both excellent and safe! And don’t say there’s a add-on for Safari as well. I’ll only accept it if the add-on is as good as the one provided by Yahoo.

Now we go for the fun part. The problems and solving them. Your attention please, this is only fun for me when I do it on my computer so it won’t be pleasure if you ask me to fix your computer! Joana this one is for you, I know how your mind thinks.. Almost as badly as mine. Oh well, we are related aren’t we? :\ Please release those crazy Christmas photos to the world! :X

I’ll start with a small OS free tip and then go for the Q/A part. If you are Portuguese like myself you just hate all the results that google gives you from .br domains. Most of the results are overrated and most of the times you just wish that they weren’t there. If this is the case just do your normal search in google but write -br in the end. Just test this, go to google and type governo brasileiro -br. It works ;)

  1. How do I get my mouse to behave like a normal one by removing this dreadful acceleration?

    Easy. Check Rúben’s blog @ http://blog.0×82.com/2007/12/mac-os-and-usb-mouse.html

  2. What’s wrong with the encoding on TextEdit? The automatic descovery does not work and even when I specifically tell him to use this encoding it won’t work. The Where is ISO 8859-15 dilemma.

    Still don’t know. Anyone? If you want to test the bug just do this (from here):

    $ echo é > ~/a.txt
    $ cat ~/a.txt
    é
    Open a.txt with TextEdit and get:
    È

    Cracked it! At least I have a partial fix for Migrating documents from Ubuntu to Mac OS X Leopard:

    cmd + space terminal enter

    {go to the directory where the file is}

    bash$ iconv -f ISO-8859-15 -t UTF-8 {filename} > UTF8-{filename}

    For me it was:

    bash$ iconv -f ISO-8859-15 -t UTF-8 Pam.tex > UTF8-Pam.tex

    And yes PAM is as in Pluggable Authentication Modules. So I have a latex work on that :P

    
    
  3. Where is type-a-name application? It’s not on the dock.

    Just press cmd + space and type what you are looking for. This is called spotlight. Either this or open Finder and go to applications.

  4. Why doesn’t it show my dashboard when I go to the left/whatever corner?

    Have you even configured your mac? Common.. Click the apple on the top left corner and go to System Preferences. Exposé and Spaces. And now that you are there take a look around and configure all the other things that you neglected.

  5. This computer is always underlining the words in red. (when the spelling is right :P If not you are a dumbass for asking this!)

    Just press cmd + mouse and change the language. Thanks Nuno Veloso from Apple Tech Team for this tip.

  6. How can I see the right mouse button menu?

    crtl + mouseclick

  7. PageUp/PageDown!?

    fn+ up
    fn + down

If after this you still feel like reading about Mac OS for rookies – like myself – you can check this section in Arun Gupta’s Blog or check this extensive list of Keyboard Shortcuts. Have fun!

Now let’s get back to work, something almost impossible when your doing a report on LaTeX and the encodings are never right.

One final touch: ctrl + alt + cmd + 8. Merry Christmas! :)

Ruby on Rails vs Java

Diffie-Hellman Java Implementation

Diffie-Hellman is a cryptographic key agreement algorithm that allows two parties that have no prior knowledge of each other to jointly establish a shared secret key over an insecure communications channel. This key can then be used to encrypt subsequent communications using a symmetric key cipher.

We were asked at cryptography classes to develop such algorithm using the core java libraries. I made a little test – I think they call it jUnit – to prove that both famous Bob and infamous Alice share the same dirty little secret.. :)Source: http://nunojobpinto.googlepages.com/diffie-hellman.zip[EDIT: As Ruben pointed out Diffie-Hellman is vulnerable to man-in-the-middle attacks. This is a purely academic work and - despite the brilliance of the response - is not intended to be used as is. If you want to learn more about this maybe you should read about station-to-station and certificates. In Portuguese you can use the resources given to cryptography masters students at University of Minho]Also if your using Netbeans IDE 6 you are probably noticing that the themes SUCK. I don’t even mean this as it’s not eye-candy, I really mean they hurt the eyes and I am already using glasses due to the overwhelming amount of time I spend at my laptop.To surpass this I advise you to download these files:

Now open your very own Netbeans IDE – wait 10 minutes for it to start – and then go to:

  • Tools -> Plugins -> Downloaded -> Add

Now add the two files you have just downloaded and change the theme in Tools -> Preferences and you are ready to go.

Ruby 1.9

De qualquer forma, até para tirar as ideias das aberrações que têm acontecido na minha universidade (mais uma vez), achei relevante o post que ele fez sobre a performance do Ruby 1.9. Aconselho a leitura. Fica, como resumo, os resultados obtido comparando a função de fibbonacci para os primeiros 36 números.

Ruby 1.8.6:       158.869s

Python 2.5.1:      31.507s

Ruby 1.9.0:        11.934s

Netbeans 6 RC2 Uninstallation Issue

Well i have been using Netbeans IDE Beta 1 for some time now.

I was using it to develop some Ruby on Rails projects. Some days ago I was in cryptography classes and tried to use the Apache Tomcat support for the Netbeans Beta 1. As I found out there was some bug in my way I decided to download the new RC2 and see if the issue got fixed in the meanwhile.

That when I first tried to uninstall Netbeans Beta 1. I got this error and still don’t know how to fix it. So I submitted it to Netbeans Community as a bug.

Anyone with the same problem got it fixed?

[UPDATE: Solution here]

I know that I have recently said that Netbeans has the best support to work on Ruby on Rails. It does. But just don’t use the beta. It’s crappy. If your on 512mb of RAM like me your computer will hate Netbeans Beta. I don’t even know if they will ever get this fixed. (Maybe a lightweight version of Netbeans is in order)

Is there such thing as the perfect IDE? We should be focusing on developing not on the IDE.

As voltas com os estudos

Acho que já se notou que não andava muito feliz com o mestrado. Como se costuma dizer, quem está mal que se mude. Foi o que fiz.

Troquei a unidade curricular de especialização de Análise e Concepção de Software pela de Criptografia e Segurança de Sistemas de Informação.

Primeiro aula (para mim claro) andamos as voltas com o JBoss. A conclusão que cheguei foi que no meio de tantos xmls de configuração qualquer um se perde e mais vale usar o Apache Tomcat! Será que não aprendem com o Ruby on Rails? Convention Over Configuration! :P Não gostei muito da forma como se criam estes webservices. O facto de termos que andar com ficheiros de configuração para trás e para frente (cliente/servidor), sermos quase obrigados a programar em Java. Era bem mais fixe se estes webservices servissem xml como respostas a pedidos, por exemplo, e que depois fossem enclapsulados numa classe de forma a responder para cada linguagem de programação. Não que perceba nada disto, ainda estou muito verdinho.

De qualquer forma fica um pedido. Se alguém conhecer um bom guia para iniciantes em JBoss diga qualquer coisa. A gerência agradece!

DB2 Express-C 9.5 Released

A new version of DB2 Express-C was made available by IBM today. As you might already know DB2 Express-C is a free dataserver without limits on database size or number of users.

We got this news from

You won’t find this new version on IBM DB2 Express-C Website, but you can download the Linux Version here and the Windows Version here.Mac version is still not available. This is probably the down side as many of us are waiting for IBM to ship a Express-C DB2 version for Macintosh. Hopefully next time?

I still didn’t tested the new DB2 but according to Antonio

Version 9.5 brings to the table a great deal of new enhancements and features. Among these there is also the reduced amount of memory requirements and the improved efficiency of operations on Linux. Oh and it will also make you rich and more beautiful. I mean, pureXML support has been greatly improved and it is a release that is sure to please many people on both Windows and Linux.

I know the t-shirt looks great. Hopefully Vítor will send me one! :P

Nova Direcção do CeSIUM

Com 31 votos a favor, um agrafador, uma tesoura e uma telefone foi hoje eleita a nova direcção do Centro de Estudantes de Engenharia de Sistemas e Informática da Universidade do Minho. Contra apenas três votos em branco (e um par de sapatilhas).

O seu novo presidente deve andar num dia de sorte já que também hoje foi anunciado como novo IBM Cenas. Parabéns!

Pessoalmente sou membro do CAOS, Centro de Apoio ao Open Source, que também faz parte do CeSIUM. Este é sem dúvida o projecto de informática feito por alunos mais dinâmico e motivante da Universidade do Minho. Espero que, num futuro próximo, sejam muitos os estudantes que possam ganhar com a divulgação e apoio que prestamos na área do software livre. Para já SVNs para membros e um mirror de software livre. Em breve outras novidades, como por exemplo um workshop de LaTeX para iniciantes dado pelo Nuno Veloso e o Ulisses Costa. Já ouvi falar também se fornecer alojamento aos membros (LAMP), com uma razoável quantidade de espaço, gratuitamente. Eu cá espero que seja LAMPr :P

É preciso ter Ruby!

Para finalizar, a todos aqueles que me conhecem como hacker da optimus, sejam bem vindos.

Para tutoriais sobre como hackear a optimus visitem esta página.

Learning Rails

TestsDamn I HATE TESTS. Unit testing is boring…
Learning rails is hard. I know it’s supposed to be easy to use. And it is.

But if you explore it a little further, and you want to know how things work, properly understand the framework and language than your in trouble. And you’ll have some headaches with it, specially on the damn tests. Knowing that in some two months I’ll have enough knowledge to create a web application is what keep me going…

When I’m done with the first study, I’ll let you all know what my impressions where. For now I’ll describe Rails framework as highly impressive and simple, but different from all you have seen before.

Some advices to who is starting, use Netbeans 6.0 and InstantRails. Visit Netbeans Documentation for quick tutorials and read the book I referred to in another post for more advanced topics.

7 tests, 7 assertions, 0 failures, 0 errors
6 tests, 12 assertions, 0 failures, 0 errors

I’m out of here.

De volta aos carris

Estou a ler o livro Ruby in a nutshell do Yukihiro que é um dos dois únicos livros que a biblioteca da minha universidade tem sobre Ruby mas, infelizmente, não se apropria a um iniciante como eu. Então andava a aprender pelo help. Não acredito nessa do estuda rails e aprende assim Ruby.

A linguagem primeiro, a framework depois.

Só que existe um pequeno problema. Na biblioteca da Universidade do Minho existem tantos livros sobre Ajax como livros sobre Rails. ZERO!

Por sorte andava por entre o Twitter e o greader quando encontrei um livro para iniciantes em rails de graça! Nos próximos 58 dias quem quiser o livro Build Your Own Ruby on Rails Web Applications pode sacar-lo AQUI. Claro que a oferta apenas vale alguma coisa se o livro tivesse qualidade mas, ao que parece, tem. Pelo menos a ver pelas reviews que andei a ler.

OFF-TOPIC: Quem achar giro programar direct3D em .NET pode ler uma iniciação neste artigo.

UPDATE: Já estou a ler o livro e aviso desde já que a parte que ensina Ruby e OOP está medíocre. Leiam algo sobre Ruby antes de lerem este livro!

DB2 Express C for Mac

I attended a conference by Vítor Rodrigues on DB2 pureXML approach on University of Minho last Wednesday. I was quite please to see that DB2 Express C was available for free and that, as far as I’m concerned, all features where available. You might not know this but most of my colleagues use Mac, so the main downfall for the presentation was the fact that no Mac version was available. Well, according to Antonio Cangiano that about to change. IBM is working on some beta version of DB2 for Mac, and it’s not just the client. It’s the whole thing. You can check for details here.

Another thing worthy of mention, the post Cangiano made about Haskell. It’s called Haskell Eye for the Ruby Guy and, in a certain way, represents that topic introduced here some days ago. Definitely worth the time you will spend reading it.

The ever growing software complexity requires the power of high level abstractions and the functional paradigm which helps us adopt a more declarative programming style where the side effects are marginalized.

Life on the rails

I found Ruby in a talk with one of my friends. We were talking about how a problem that can be solved in Haskell in one line of code, could take hundreds to do so in Java or C#. It was obvious that, for some specific problems, Haskell was simpler and adequate.

Want a sample? Code permutation with n levels in C.

perms xs 0 = [[]]
perms xs n = [ p : ps | p <- xs, ps <- perms xs (n - 1)]

And like this he introduced me to Ruby on Rails. I was very thrilled to see a language that is dynamic, object oriented and adequate for web developing. I immediately thought about learning it, I just love learning new languages.

Today I checking my feeds and found a post about seven reasons to switch back to PHP (from Ruby).

It seems Ruby is like Haskell: the code looks greats and promises a lot, but it still doesn’t get where imperative languages do. (I’m still going to learn it, I just can’t resist it)

For now I’m waiting for a language that joins all that is good from imperative, functional, logic and object oriented paradigms.

If you know such programming language leave it as a comment.

 

 

PHP $61,000

 

Ajax $76,000

 

Ruby $70,000

 

Java $77,000

 

C# $78,000

 

Haskell $52,000

 

View Larger Salary Graph

Follow

Get every new post delivered to your Inbox.