[Ruby] How to get the name of the calling method?

[Ruby] How to get the name of the calling method?

I was about to run a rake task which would make important changes in my database.

My code was similar to this:

def migrate_active_accounts
  accounts = Account.active
  # Code to migrate accounts here...
end

def migrate_inactive_accounts
  accounts = Account.inactive
  # Code to migrate accounts here...
end

This migration was very critical. Thus, I decided to log everything to make sure it would run as expected. So I wrote a separate method to log what accounts were going to run by which method. In order to do that, I’d need to know which method was calling my logger method. I ended up finding the answer on StackOverflow (where else I would? :p).

Solution

As usual, Ruby has a neat solution for it: Kernel module has a caller_locations method, which returns an array with the current execution stack. So all we need to do is to use caller_locations.first.label to get the first element from the stack and then get its label.

My final code was looking like the following:

def migrate_active_accounts
  accounts = Account.active
  log_migration_info(accounts)
  # Code to migrate accounts here...
end

def migrate_inactive_accounts
  accounts = Account.inactive
  log_migration_info(accounts)
  # Code to migrate accounts here...
end

private

def log_migration_info(accounts)
  caller_method = caller_locations.first.label

  Rails.logger.info "Running [MyClass##{caller_method}]
    for the following accounts: #{accounts.map(&:id).to_sentence}"
end

Ruby prior to 2.0

If you’re using an old version of Ruby (even though you shouldn’t), you’ll need to use caller method along with a regular expression:

caller.first[/`(.*)'/, 1]

Happy hacking!

Prevent Rails from writing development/test log files

Prevent Rails from writing development/test log files

I can’t remember the last time I needed to open/read log/development.log or log/test.log. This is just consuming disk space unnecessarily (my test.log easily reaches more than 1 GB!). After talking to some other developers, all of them agreed they don’t use it as well.

So what I’ve been doing in my projects is adding the following code. Note that it’ll still display the logs through the STDOUT though.

Rails 4 or higher

# config/environments/development.rb

# Prevents from writing logs on `log/development.log`
logger           = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger    = ActiveSupport::TaggedLogging.new(logger)
# config/environments/test.rb

# Prevents from writing logs on `log/test.log`
config.log_level = :warn
logger           = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger    = ActiveSupport::TaggedLogging.new(logger)

Rails 3

# config/environments/development.rb

# Prevents from writing logs on `log/development.log`
logger        = ::Logger.new(STDOUT)
config.logger = ActiveSupport::TaggedLogging.new(logger)

# Replace `config.active_support.deprecation = :log` with:
config.active_support.deprecation = :stderr
# config/environments/test.rb

# Prevents from writing logs on `log/test.log`
config.log_level = :warn
logger           = ::Logger.new(STDOUT)
config.logger    = ActiveSupport::TaggedLogging.new(logger)

Ps.: I’ve sent a suggestion to rubyonrails-core mailing list to make it default, let’s see their thoughts.

Puma vs. Unicorn

Puma vs. Unicorn

TL; DR – You should start using Puma.

Rails has switched the default server from Webrick to Puma in Rails 5!

It also supports Action Cable (one of the new features from Rails 5) and Basecamp said they’re using Puma in production.

I was wondering if Puma has been in fact better than Unicorn so I’ve read some blog posts about it:

Basically, the answer is yes – it is a bit better, but don’t wait for a huge improvement. I’d say it might be a good idea if you’re:

  • about to start a new project;
  • about to migrate your current project to Rails 5;
  • unhappy with your Rails 3 / 4 app server performance.
Aprenda a programar

Aprenda a programar

Parte I – Desenvolvimento de aplicações web

Primeiramente, assista esse vídeo:

Depois leia esse post: blog.lucascaton.com.br/2014/05/21/como-aprender-ruby-e-rails.

Finalmente, entre nesse grupo para acompanhar as novidades ou para tirar dúvidas: Ruby on Rails Brasil.

Parte II – Desenvolvimento de aplicações iOS (iPhone, iPad, Apple Watch, Apple TV)

Entre nesse grupo (Slack): iOS Dev BR.

Qualquer dúvida, mande nos comentários abaixo :-)

Rake task to import a production DB dump

Rake task to import a production DB dump

Every now and then I need to write a script (rake task) to import a production database dump.

This is code I usually use:

require 'yaml'

namespace :db do
  desc 'Downloads and imports a production DB dump'
  task :import_production_dump do
    puts '➙ Generating production DB dump...'

    execute_on_server %(
      PGPASSWORD="`cat /var/www/project/current/config/database.yml | \
        grep password | awk '{ print $2 }'`" \
        pg_dump database_name -h custom_url.rds.amazonaws.com -U user_name \
        --column-inserts --no-owner --no-privileges > backup.sql
    )

    puts '➙ Downloading production DB dump...'
    system "scp #{server_user_and_host}:#{backup_file_name} ."

    puts '➙ Deleting production DB dump...'
    execute_on_server 'rm backup.sql'

    puts '➙ Cleaning your local DB...'
    %w(drop create).each { |task| Rake::Task["db:#{task}"].invoke }

    puts '➙ Importing production DB dump...'
    system "bin/rails db development < #{backup_file_name} > /dev/null"

    puts '➙ Removing local dump...'
    system "rm #{backup_file_name}"

    puts '➙ Done!'
  end

  def execute_on_server(commands)
    system %(ssh -T #{server_user_and_host} << 'SSH'
      #{commands}
    SSH).split("\n").map(&:strip).join("\n")
  end

  def server_user_and_host
    'username@example.com'
  end

  def backup_file_name
    'backup.sql'
  end
end

Let me know in the comments if you have a better solution! Perhaps a tiny gem? ツ

Why I regenerated my SSH key and maybe you should too

Why I regenerated my SSH key and maybe you should too

security

I think we all agree it’s a good practice to regenerate your SSH key from time to time. Not sure about you, but the first thing that comes to my mind when I think about that is: it’d take forever to replace my key in all servers I need to access, all online services that use my key, etc.

Overcoming my laziness, I decided at least to list every place I’d have to update it. Interesting fact: it turned out that it was pretty much a small list:

  • Servers
  • Github
  • BitBucket
    • Although now it looks more reasonable, I was still lazy to do it. Then, a few days ago, I noticed that Github recommends the use of HTTPS instead of SSH for Git repositories syncs:

      Github - HTTPS vs SSH

      What does one thing have to do with another? Well, by using HTTPS, you don’t need to upload your SSH key to Github (check this out: mine isn’t longer at Github). BitBucket also supports it, which means I’d be able to regenerate my SSH key without having to upload it again to these services.

      Servers

      What’s left? Servers! From now on, every time I realise it’s time to regenerate my SSH key, all I need to update are the servers. I ended up making a list of servers that I’d need to update and found out in the end it wasn’t a big list and it’d be way easier than I thought it would.

      Let’s face the truth: I had been using the same SSH key in the last 5 years or so and it’d be totally worth it to ensure my security as well as the security of the projects from the company I work for.

      Becoming safer

      There’s more! This is the interesting part of this post: I’ve changed other things that made everything even safer:

      1. My new SSH key uses 4096 bitsrecommended by Github – instead of the default (2048 bits).
      2. As I mentioned before, I’ve changed all my local repositories to use HTTPS instead of SSH (see how in the end of this post).
      3. I’m now using a personal access token rather than my Github password (you can create it here), along with two-factor authentication, which I was already using.
      4. Cool, but would I need to type this token every time? Nope. There’s a nifty tool called ssh-agent that can save your token. If you’re using OS X, it’s even easier: Keychain can save and encrypt your token for you.
      5. My SSH key now has a passphrase, also saved encrypted in OS X’s Keychain, which means I don’t need to type it every time either.

      HTTPS is faster!

      According to some tests I made here, HTTPS is faster than SSH:

      # SSH
      $ time git clone git@github.com:rails/rails.git
      # 24.28s user 9.56s system 49% cpu 1:08.20 total
      
      # HTTPS
      $ time git clone https://github.com/rails/rails.git
      # 13.52s user 6.41s system 39% cpu 50.730 total
      

      In order to use HTTPS in my Git repos, do I need to re-clone every project?

      Nope. Just edit the file .git/config (within your project folder) and replace:

      url = git@github.com:username/repo.git

      with:

      url = https://github.com/username/repo.git

      Conclusion

      Regenerating your SSH key every now and then isn’t painful as you think it is. I’d recommend doing it every 3 years or even less if you’re paranoic or you work on something critic.

What is “frozen_string_literal” in Ruby?

What is “frozen_string_literal” in Ruby?

ruby3

Freezing Strings feature improves apps performance by freezing Strings. So, Matz – Ruby’s creator – decided to make all String literals frozen (immutable) by default in Ruby 3.0.

In order to have a transition path to this coming big change, it was decided to have a magic comment at the beginning of files, so you can use in Ruby 2.3.

To do so, just add this comment in the first line of your files:

# frozen_string_literal: true

class YourClass
  # ...
end

Trying adding it to your spec_helper file and let me know in the comments if you performance improved!

More info: Ruby issue #8976.

If you really need to create a monkey patch, do it properly

If you really need to create a monkey patch, do it properly

Ruby

Sometimes we need to create a monkey patch for a gem or external lib.
In these cases, it’s good to force it to fail if the gem has been bumped up:

if Paperclip::VERSION != '1.2.3'
  # If you see this message, please test removing this file
  # If it's still required, please bump up the version above
  fail 'Please remove me, Paperclip version has changed'
end

If the gem doesn’t provide you the version through a method, you can solve it with:

if Bundler.load.specs.find { |gem| gem.name == 'paperclip' }.version.to_s != '1.2.3'
  # If you see this message, please test removing this file
  # If it's still required, please bump up the version above
  fail 'Please remove me, Paperclip version has changed'
end

Or even when you’re waiting for a new Rails version, e.g.:

fail 'Remove this file' if Rails::VERSION::MAJOR >= 5

Ps.: Paperclip gem was just an example :-)

Como eu faço backups

Como eu faço backups

Faz tempo que penso em escrever sobre as ferramentas e estratégias que utilizo para backups. Ao escutar esse episódio do Tecnocast sobre o assunto, decidi que era hora de documentar o que eu faço.

Meus arquivos pessoais (aka. pasta ~/)

my personal files

A pasta do meu usuário possui 3 cópias extras:

1. Assino o plano familiar (U$ 12,50 / mês) do CrashPlan, o qual realiza backup automatico e em tempo real do meu computador, da minha esposa e ainda do da minha mãe. Todos os dados ficam na nuvem e eu consigo recuperá-los a qualquer momento, a partir de qualquer lugar, de qualquer computador.

2. A segunda cópia extra dos meus arquivos ficam no meu TimeCapsule, que rodam diariamente de forma automática através do Time Machine.

3. Por fim, faço uma cópia mensal num HD externo (que é bem rápido graças à sua conexão USB 3) utilizando o rsync pra realizar um backup diferencial. O comando / parametros que utilizo para isso é:

rsync -a --progress --delete --delete-excluded --exclude "*.DS_Store" /Users/lucascaton/ /Volumes/Backups/lucascaton/

Atenção: não esqueça do / no final de cada path do comando acima.

Arquivos importantes

important files

Ficam dentro da pasta do Dropbox. Ou seja, uma cópia extra além do CrashPlan, Time Machine e HD externo mencionados acima.

Arquivos encriptografados

important files

Se você utiliza OS X macOS, é fácil criar uma pasta protegida com senha (tecnicamente é uma imagem de disco, mas você pode encarar como se fosse uma pasta). Veja como fazer isso nesse artigo de suporte da Apple.

Nessa pasta, eu guardo:

  • Códigos de recuperação de servicos com autenticação de 2 fatores;
  • Screenshots dos QR codes de autenticação de 2 fatores. É extremamente útil se você precisar resetar seu celular, já que o Google Authenticator (e outras apps) não salvam esses dados na nuvem (por motivos de segurança);
  • Chaves privadas SSH (pra acessar servidores);
  • Algumas poucas senhas que prefiro manter nessa pasta do que em gerenciadores de senha como o 1Password, o qual eu uso para todo o resto (veja mais informações sobre o 1Password no tópico “Senhas” no final desse artigo.

Arquivos que não ficam no meu computador

other files

Alguns arquivos eu não mantenho no meu computador por serem muitos grandes ou simplesmente por não fazer sentido tê-los comigo o tempo todo. Um exemplo são os vídeos do Reza a Lenda.

Eu os mantenho no Time Capsule e mensalmente faço um backup destes para o mesmo HD que mencionei no começo do artigo, também utilizando o rsync.

VPS

vps hosting

Faço backup das minhas VPSs através de scripts que realizam backups mensais (os quais rodam diretamente no servidor) e mandam esses arquivos para o meu computador (de novo através de um rsync).

Documentos (RG, CPF, passaporte, etc)

passport

Tenho foto de todos os meus documentos e estes ficam em uma pasta específica dentro do meu Dropbox, a qual é sincronizada automaticamente com o meu celular (através do iTunes), tornando-se disponível no meu celular mesmo quando não há internet disponível.

Fotos

pictures folder

Não ficam na nuvem (por enquanto). Também não utilizo nenhum software para gerenciá-las, apenas pastas organizadas por datas. E não chega a ser um problema: consigo ser disciplinado e manter tudo organizado. Nunca deixo nada no celular, quando o conecto ao computador eu já copio as fotos pro lugar apropriado.

Apesar disso, o novo Google Photos parece um bom lugar pra mantê-las de forma segura.

Músicas

spotify

100% das minhas músicas estão no Spotify. Assino o plano premium, então elas também ficam disponíveis off-line no meu celular.

Emails e calendário

gmail-and-google-calendar

Versões web do Gmail Inbox e Google Calendar. Simples assim.

Senhas

1password

Gerencio todas as minhas senhas através do 1Password, mas tem uma regra de ouro pra evitar problemas se a segurança do 1Password um dia falhar: a senha do meu Inbox / Gmail não está salva em lugar algum, está apenas na minha cabeça – assim eu consigo recuperar a senha de qualquer serviço caso necessário, utilizando o recurso “Esqueci minha senha”, que a maioria dos serviços oferece.

Filmes e séries

itunes-and-netflix

Eu costumava alugar filmes e séries na locadora suéca (também conhecida como locadora do Paulo Coelho), mas comecei a fazer as contas: eu assisto uma média de 12 séries por ano, cada uma custa em média $25 por temporada no iTunes, ou seja, $25 por mês. Às vezes tem no Netflix e acabo gastando menos. Já alugar um filme recém-lancado em HD no iTunes custa em média $4. Moral da história: decidi parar completamente de fazer pirataria e comprar / alugar tudo da forma correta :-)

Conclusão

Ok, eu sei que sou um pouco (muito?) paranóico, mas pelo menos nunca perdi nada :D
Me conte nos comentários abaixo como você faz seus backups e o que você achou desse post!

8 motivos pra programar em inglês

8 motivos pra programar em inglês

Vejo muitos brasileiros escrevendo código em português. Na faculdade até pode fazer um pouco de sentido por mais didático, mas vou apresentar alguns motivos pelos quais isso deve ser evitado no mundo real:

1. O motivo mais importante: inglês é o idioma internacional para código (e para documentações). Mais especificamente, o inglês americano é o padrão. Eu trabalho em uma empresa australiana e embora a Austrália siga a gramática britânica, o código que escrevemos segue a gramática americana (exemplo: “color” e não “colour”). Então se esse é o padrão mundial, por que não segui-lo?

2. Se você pretende um dia trabalhar fora do Brasil, potenciais empresas querendo te contratar vão querer ver seu código, mas não irão entender se estes estiverem em português. Então procure deixar seus repositórios no Github com código e documentação em inglês.

3. Os comandos e palavras-chave de linguagens em programação são em inglês, então mesmo que você queria escrever em português, vai acabar ficando inevitavelmente uma mistura.

4. Algumas linguagens e frameworks estão preparados para entender o inglês em termos de semântica. Exemplo: o Ruby on Rails sabe que a tabela no banco de dados para um determinado model deve ser sempre o nome do model no plural. Ou seja, ao ter um model “Person”, ele vai procurar uma tabela “people”.

5. Contribuições para projetos open-source devem ser em inglês. Eu sinceramente não conheço um projeto open-source famoso que não esteja em inglês.

6. Muitas empresas no Brasil já escrevem códigos em inglês. Então se eventualmente você começar a trabalhar em um dessas empresas, você terá que se adaptar de qualquer forma.

7. Acentos, “ç” e caracteres especiais não funcionam bem em todas as linguagens, fazendo que você tenha palavras escritas de forma incorreta se você as escrever em português.

8. Você treina e melhora seu inglês :-)

Measuring and improving your Rails app quality

Measuring and improving your Rails app quality

I’ve just written a blog post on the NetEngine’s blog:

http://netengine.com.au/blog/measuring-and-improving-your-rails-app-quality/

I hope you enjoy it.

CampJS 2014 – the best nerd event I ever attended

CampJS 2014 – the best nerd event I ever attended

A few days ago I was in CampJS, the best nerd event I ever attended.

campjs

This is the official website (which is pretty nice by the way): http://campjs.com/.

Why it was the best in my opinion:

  • It happened in an amazing place – to be near of the nature, changing the usual environment is renewable. I definitely recommend to try it.
  • I had the chance to talk to a lot of other Javascript developers
  • Awesome talks and workshops
  • Good food and beers
  • A live podcast was recorded in there

A friend of mine (@erikEcoologic) have written an awesome blog post about the event, so go check it out! ;)

A special thanks to @brucestronge and to NetEngine for the tickets!

Video & some pictures

IMG_0

IMG_1067

IMG_1099

IMG_1199

IMG_1202

IMG_1206

IMG_1267

Como você contribui para um mundo melhor?

Como você contribui para um mundo melhor?

Somos consumidores assíduos de conteúdo (offline e especialmente online). E a idéia desse post é listar o que eu tenho feito em troca disso e também incentivar aos que não fazem a considerar a idéia! ツ

  • Eu mantenho esse blog desde 2009 (mais de 5 anos já!) com posts sobre Ruby, Rails, Linux, OS X, mobile, etc;
  • Mantenho também um canal no Youtube com screencasts técnicos;
  • No meu Github tem alguns projetos open-source, alguns bastante genéricos, como meus dotfiles e meus vimfiles;
  • Criei e mantenho alguns grupos de discussão, como Vim Users BR, Swift BR, Neo4k BR e Gxt (ExtGwt) [BR];
  • Faço parte do staff que cuida dos eventos do GuruSP. Quando eu morava em São Paulo eu ajudava mais, agora ajudo apenas remotamente.
  • Tenho um blog pessoal também, onde não escrevo sobre coisas técnicas;
  • Meu twitter é basicamente para discussões relacionadas à tecnologia;
  • Para finalizar: faço sempre que possível palestras e apresentações (às vezes online) sobre ferramentas interessantes que tenho usado (infelizmente algumas foram feitas em empresas e não estão públicas).

Não ganho nada fazendo essas coisas, mas é recompensador! ¯\_(ツ)_/¯

Mandem seus 2 cents nos comentários!

[Screencast] Ruby on Rails – Assets / Assets Pipeline

[Screencast] Ruby on Rails – Assets / Assets Pipeline

Mais um screencast gravado!
Esse sobre como funcionam os assets e o Assets Pipeline do Rails.

Assista outros screencasts do meu canal:

Links comentados no vídeo:

How to use command line on Mac OS X

How to use command line on Mac OS X

A friend of mine (who came from Windows world) have bought a Mac recently and he asked me how to use command line on Mac OS X:

My answer was:

1) 99% of commands are identical in Linux. This is good news as there are a lot of material about it available on the Internet;

2) Terminal.app from OS X is cool, but it’s not perfect. I (and 90% of developers I know) use iTerm2 (http://iterm2.com/). It’s light (3mb), free, open-source, has a better interface than the native one and it rocks! Best terminal I’ve ever used.

3) This is the most useful topic in my answer: an awesome cheat-sheet with command line commands made by the Git-tower team;

4) To finish: I’ve recorded a screencast showing up how to create scripts in OS X and Linux (similar to BAT file in Windows). Unfortunately this is only available in portuguese:

What do I have in the OS X’s menu bar?

What do I have in the OS X’s menu bar?

menubar

Application Description Type
Caffeine Prevent your Mac from automatically going to sleep, dimming the screen or starting screen savers Free
ColorSnapper Color picker Paid
1Password Password manager Paid
Dropbox File hosting service Free / Paid
CrashPlan Online data backup in real time Paid
Spectacle Window control Free / Open source
Evernote I love Evernote, but I don’t use this icon for anything.
When I close it, it returns automatically ¯\_(ツ)_/¯
Free / Paid
Chrome notifications I never really use it, but I guess there’s no way to remove it though Free
Text Expander Custom keyboard shortcuts into frequently-used texts Paid
AirPlay Play content on your TV via Apple TV Free
Time Machine Built-in backup feature of OS X that works with an external HD or Time Capsule Free
Um conselho para estudantes de computação

Um conselho para estudantes de computação

graduation cap diploma isolated on a white background

Enquanto eu divulgava o projeto do meu curso de programação pelas redes sociais, uma pessoa me fez a seguinte pergunta:

Terminei meu 1º semestre de Ciência da Computação e por enquanto, tudo parece tranquilo. Mas não deixo de me preocupar quando a coisa ficar realmente “interessante”. Fico pensando naqueles códigos de tamanho imenso, na lógica maciça empregada nele. Será que não enche o saco? Resolver bugs, procurando linha por linha onde está o erro? Valeu Lucas!

Minha resposta:

Olá! Interessante sua pergunta. Me lembro que na época de faculdade eu fazia estas mesmas perguntas :-)

Apesar de projetos / códigos crescerem, eu diria pra você não se preocupar muito com isso agora. Existem ferramentas que te ajudarão a organizar tudo isso. Exemplos: criação de testes automatizados, controlador de versões (como Git), bons editores (ou IDEs), etc.

Se você quiser saber como será sua profissão futuramente, uma boa maneira de ver isso na prática é olhar os pull requests de algum projeto open-source e ver o que está sendo discutido lá. Aproveite e veja os códigos também, você vai ver que mesmo em um projeto grande, não existe bicho de 7 cabeças (ok, algumas raras vezes existe). A página de pull requests do Rails é um bom lugar pra ver isso: https://github.com/rails/rails/pulls.

Eu sou completamente apaixonado por essa área e não consigo me ver fazendo outra coisa. O bacana é que você pode trabalhar com muitas coisas diferentes, como desenvolvimento web (backend ou frontend), desenvolvimento de jogos, desenvolvimento de apps para iOS / Android, robótica, IA, BI, entre outros – a lista é grande. Enfim, é uma área muito bacana :)

Claro: nem tudo são flores. Tem dia que enche o saco, tem dia que nada funciona e isso pode ser um pouco irritante. Mas nada que uma noite bem dormida e um bom café pra renovar e partir pro código novamente.

Minha dica final é: siga pessoas da área. Mas não se limite somente à blogs, veja também o que bons programadores (brasileiros e gringos) estão falando nas redes sociais, leia bons livros, participe de eventos da comunidade (exemplo: GuruSP), seja curioso (pergunte sempre) e não se limite somente ao que a faculdade pode te oferecer.

Durante o período de faculdade você tem basicamente 3 fontes de aprendizado: sozinho (auto-ditata), através de colegas e através das aulas (professores). Todas são importantes, mas nunca siga seu caminho utilizando apenas as aulas. Conseguir ler bons livros, criar uma boa base de conhecimento na área ou fazer boas amizades durante esse período é essencial. Além disso, colegas da faculdade são potenciais futuros colegas de emprego (podem te ajudar a conseguir um) ou ainda futuros sócios! :)

Meu projeto (curso) “Aprenda a programar” está no Catarse!

Meu projeto (curso) “Aprenda a programar” está no Catarse!


Atualização:

A meta infelizmente não foi atingida. Porém você pode ler o post a seguir para saber como você pode aprender a programar: blog.lucascaton.com.br/2016/03/12/aprenda-a-programar.


 

Tem um vídeo explicativo bem no começo da página!

http://www.catarse.me/pt/aprendaaprogramar


Screen Shot 2014-07-31 at 1.37.48 pm

[Off-topic] Um novo blog pessoal

[Off-topic] Um novo blog pessoal

Decidi apagar todos os outros blog que eu tinha e manter apenas este que você está lendo para assuntos técnicos e um recém criado no Medium, que aliás é uma excelente plataforma, estou gostando muito!

Segue o link do novo blog: https://medium.com/@lucascaton.

Coisas sobre Linux que me chamaram a atenção recentemente

Coisas sobre Linux que me chamaram a atenção recentemente

LinuxVersions

Você pode não saber (ou esquecer às vezes), mas o Linux está muito presente na sua vida. Mesmo que você não o use diretamente como sistema operacional principal, mais da metade dos sites que você acessa está rodando em plataforma Linux. Isso inclui empresas gigantes como Google, Facebook, Twitter, Soundcloud, Amazon, Spotify, etc – a lista é muito, mas muito longa. A maioria dos filmes que você assiste utilizam Linux para renderizar cenas extremamente complexas que às vezes levam semanas ou mesmo meses para serem renderizados. O sistema móvel Android também é um Linux também caso você não saiba. E o seu roteador e a sua SmartTV provavelmente rodam Linux também!

Embora atualmente meu computador principal rode OS X, eu estou em contato com vários servidores que rodam Linux os quais acesso frequentemente. Além disso, utilizei Linux como S.O. principal de 2007 à 2011, através das distros Ubuntu e OpenSUSE (além de outras que utilizei por pouco tempo, como Slackware e Debian).

Na última semana várias coisas me chamaram a atenção no mundo Linux e esse é o motivo desse post:

1. O último episódio do podcast do Hack ‘n’ Cast (v0.3) foi uma introdução ao Linux e foi muito bom, vale a pena escutar: http://mindbending.org/pt/hack-n-cast-v03-introducao-ao-gnulinux.

2. Um amigo que é programador disse que nunca (palavra forte!) usaria Linux porque nem criar um script similar ao batch do “Janelas” ele conseguia. Bom, pensando que isso pudesse ser útil para mais pessoas, gravei um screencast ensinando como criar scripts no Linux e no Mac OS X: http://youtu.be/W84Ok6XGnow.

3. Assisti à uma ótima palestra chamada “Linux Sucks”: http://youtu.be/5pOxlazS3zs.

4. Lembrei e reli o excelente ponto de vista do Pothix sobre porque ele deixou o OS X e voltou a usar Linux: http://pothix.com/blog/development/menos-mac-e-mais-linux.

5. Pra finalizar (e descontraír), há um tempo atrás eu ganhei de um amigo que trabalha na RedHat um chapél vermelho (red hat, rá!), o qual foi parar na cabeca do Tux que eu tenho na minha estante, vide fotos abaixo. Ficou bem bacana! :-)

1

2

Bom, essa não é a primeira vez que eu escrevo sobre Linux e também não será a última. Linux é muito mais importante do que as pessoas pensam. Pense 3 vezes antes de subestimar o sistema do pinguim! ;)

Swift BR – grupo de discussão sobre a nova linguagem lançada pela Apple

Swift BR – grupo de discussão sobre a nova linguagem lançada pela Apple

swift-icon

A idéia desse grupo é fazer com que os usuários possam conhecer uns aos outros, compartilhando e discutindo idéias interessantes relacionadas à essa nova linguagem lançada pela Apple, para substituir o Objective C como linguagem padrão para desenvolvimento de aplicações tanto OS X quanto iOS.

https://groups.google.com/d/forum/swiftbr

Como aprender Ruby e Rails

Como aprender Ruby e Rails

ruby_rails

Vários amigos tem me perguntado como podem aprender a programar em Ruby e Rails. Vou postar aqui os mesmos vídeos e dicas que mandei pra eles, caso alguém tenha interesse também:

An awesome Wiki built with Ruby and Rails!

An awesome Wiki built with Ruby and Rails!

I’ve been worked on a small (but awesome) open-source project.

I’m talking about ruby_wiki – a simple wiki built with Ruby on Rails:
https://github.com/lucascaton/ruby_wiki

As I said before – it’s quite simple, although it works fine.
Anyway, would be nice to have more features in this project, so, if you’re a developer and have any interest in that, feel free to fork the project and contribute.

Some screenshots:


1


2


3


4


5


6

Have a Rails 2 app? You can run it on the newest Ruby!

Have a Rails 2 app? You can run it on the newest Ruby!

old_rails_with_new_ruby

Do you have a legacy Rails application which is still running on Rails 2?

There are several reasons to migrate your application to new Rails versions, like to improve the security, to be able to use a better syntax, to take advantage of new features and also because most of current gems will only work on Rails 3 or higher. However, sometimes it’s hard to do that, especially for big projects. And certainly today there’re many project still running on Rails 2.

But there’s one good thing you can (and should) do! I’m talking about to use the newest Ruby version. Yes, I’m serious. When I wrote this post, the current Ruby version was 2.1.1 – and it’s not so hard to get it working fine with Rails 2.

Obviously, would be better if you have a good test coverage.

That said, let’s do it in a few steps:

Replacements

1. Gemfile

Rails 2 apps don’t use Bundler by default, so if you don’t have Bundler managing your gems yet, you should check here how to do that.

# There's no way to ensure that next Ruby versions will work,
# but so far the current one works fine:
ruby '2.1.1'

# The same for rake:
rake '10.1.1'

# You might need the iconv gem:
gem 'iconv'

2. Rakefile

# Replace:
# require 'rake/rdoctask'

# with:
require 'rake/task'

3. config.ru

# Replace:
# require 'config/environment'

# with:
require File.dirname(__FILE__) + '/config/environment'

4. FasterCSV => CSV

Replace all FasterCSV constant with CSV. Also, include require 'csv' to relevant files (or include this require to config/environment.rb).

Inclusions

5. config/environment.rb

# Include this before the `Rails::Initializer.run` line:
if RUBY_VERSION >= '2.0.0'
  module Gem
    def self.source_index
      sources
    end

    def self.cache
      sources
    end

    SourceIndex = Specification

    class SourceList
      # If you want vendor gems, this is where to start writing code.
      def search(*args); []; end
      def each(&block); end
      include Enumerable
    end
  end
end

6. config/initializers/paperclip.rb

# The patches below are needed when using an old version of PaperClip + Ruby 2.x
# https://github.com/thoughtbot/paperclip/issues/262
# https://github.com/thoughtbot/paperclip/commit/1bcfc14388d0651c5fc70ab9ca3511144c698903

module Paperclip
  class Tempfile < ::Tempfile
    def make_tmpname(basename, n)
      extension = File.extname(basename)
      sprintf('%s,%d,%d%s', File.basename(basename, extension), $$, n.to_i, extension)
    end
  end
end

module IOStream
  def to_tempfile
    name = respond_to?(:original_filename) ? original_filename : (respond_to?(:path) ? path : 'stream')
    tempfile = Tempfile.new(['stream', File.extname(name)])
    tempfile.binmode
    self.stream_to(tempfile)
  end
end

New files

7. config/initializers/ruby2.rb

# This is a very important monkey patch to make Rails 2.3.18 to work with Ruby 2+
# If you're thinking to remove it, really, don't, unless you know what you're doing.

if Rails::VERSION::MAJOR == 2 && RUBY_VERSION >= '2.0.0'
  module ActiveRecord
    module Associations
      class AssociationProxy
        def send(method, *args)
          if proxy_respond_to?(method, true)
            super
          else
            load_target
            @target.send(method, *args)
          end
        end
      end
    end
  end
end

8. config/initializers/rails_generators.rb

It’ll prevent Rails migration generator from stop working, otherwise you’ll receive the following error message:

undefined local variable or method `vars' for #<Rails::Generator::Commands::Create

(Thanks Mr. S and jnwheeler44 for helping me to fix this one)

# This is a very important monkey patch to make Rails 2.3.18 to work with Ruby 2+
# If you're thinking to remove it, really, don't, unless you know what you're doing.

if Rails::VERSION::MAJOR == 2 && RUBY_VERSION >= '2.0.0'
  require 'rails_generator'
  require 'rails_generator/scripts/generate'

  Rails::Generator::Commands::Create.class_eval do
    def template(relative_source, relative_destination, template_options = {})
      file(relative_source, relative_destination, template_options) do |file|
        # Evaluate any assignments in a temporary, throwaway binding
        vars = template_options[:assigns] || {}
        b = template_options[:binding] || binding
        # this no longer works, eval throws "undefined local variable or method `vars'"
        # vars.each { |k, v| eval "#{k} = vars[:#{k}] || vars['#{k}']", b }
        vars.each { |k, v| b.local_variable_set(:"#{k}", v) }

        # Render the source file with the temporary binding
        ERB.new(file.read, nil, '-').result(b)
      end
    end
  end
end

RSpec

9. Make sure you’re using the last compatible version with Rails 2.3.18:

gem 'rspec', '1.3.2'
gem 'rspec-rails', '1.3.4'

10. Remove the file script/spec.

11. lib/tasks/rspec.rake

Remove all the following lines:

gem 'test-unit', '1.2.3' if RUBY_VERSION.to_f >= 1.9
rspec_gem_dir = nil

Dir["#{Rails.root}/vendor/gems/*"].each do |subdir|
  rspec_gem_dir = subdir if subdir.gsub("#{Rails.root}/vendor/gems/","") =~ /^(\w+-)?rspec-(\d+)/ && File.exist?("#{subdir}/lib/spec/rake/spectask.rb")
end

rspec_plugin_dir = File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/rspec')

if rspec_gem_dir && (test ?d, rspec_plugin_dir)
  raise "\n#{'*'*50}\nYou have rspec installed in both vendor/gems and vendor/plugins\nPlease pick one and dispose of the other.\n#{'*'*50}\n\n"
end

if rspec_gem_dir
  $LOAD_PATH.unshift("#{rspec_gem_dir}/lib")
elsif File.exist?(rspec_plugin_dir)
  $LOAD_PATH.unshift("#{rspec_plugin_dir}/lib")
end

Ruby syntax

12. Some details has been changed in Ruby syntax, especially from 1.8.x to 1.9.x.

Example 1:

# Replace:
when 'foo': bar

# with:
when 'foo' then bar

Example 2:

The behaviour for protected methods in new Ruby versions is a little bit different. See more in this post.

# In some cases, you might need to replace:
respond_to?(:foobar)

# with:
respond_to?(:foobar, true)

Example 3 (Yaml files):

# Replace:
order: [ :day, :month, :year ]

# with:
order:
  - :year
  - :month
  - :day

Ruby changes

13. The default encoding for Ruby 2.0 (or higher) is UTF-8. So, remove all the code similar to:

# encoding: utf-8

Or:

$KCODE = 'UTF-8'

Important note (included on July 27, 2014)

Check below the comments of this post — Gabriel Sobrinho, Kyle Ries and Greg made some very interesting and useful comments.

Conclusion

Each project could have different issues.
But I hope this little guide helps you to use new Ruby versions in legacy Rails applications!