Rafael Souza
web application programmer
Posts
O @sa_vini me convidou para participar do último meme do momento que é descrever o ambiente onde nós, todos os dias, desenvolvemos essa coisa maravilhosa chamada software. Então lá vai.
OS
Atualmente sou um feliz usuário do Mac OS X, pra mim, ainda não existe nada igual. Depois de usar Windows por muito tempo e tentar duas distros Linux (ArchLinux e Ubuntu), comprei um Macbook e me tornei uma pessoa mais feliz.
Ruby
Eu gosto de fuçar em bastante coisa que eu vejo por ai, e Ruby sem dúvida, foi a melhor coisa que eu já fucei até hoje. Uma linguagem com sintaxe simples, porém bem poderosa e altamente extensível. Hoje Ruby é a linguagem que uso pra tudo (apesar de eu estar numa baita pilha para usar Javascript com node.js).
Git
Não sou um super-usuário de Git, mas me viro bem com ele, já usei Visual Source Safe e Subversion, porém o Git é imbatível, prático para as coisas simples e poderoso para todo o resto. Se ainda não usou, use.
Editor
Depois de uma ou duas semanas, tentando pela quinta/sexta vez, usar VIM, voltei para o TextMate, acho legal a idéia de poder fazer tudo pelo editor, mas eu só quero programar, mais nada. :)
Chrome
Na minha humilde opnião, o melhor browser já feito até hoje.
Música
Meu iTunes fica ligado direto. Pra falar bem a verdade eu não sei se música influencia na minha produtividade, já que desde sempre trabalho ouvindo música. Acho que ouço mais por hábito mesmo. Aliás, exatamente agora tá rolando um remix de Train - Hey, Soul Sister, bem bacana.
Local
Hoje trabalho no aconchego do meu lar com três cadelinhas me fazendo companhia, porém esse lar é quente like a hell e o ventiladorzinho que eu tenho aqui - praticamente em cima de mim - não dá conta do recado. Espero me mudar em breve. :)
É isso ai, meu ambiente não é lá grande coisa, nem é muito diferente dos outros, mas para as minhas tarefas diárias ele é mais do que suficiente.
Convido para participar também, @juliogreff e @joaomilho
Essa é uma daquelas que é fácil mas o cara nunca lembra como fazer, já precisei disso algumas vezes e sempre tinha que recorrer ao seu Google para descobrir.
1
| |
Retirado daqui: http://snippets.dzone.com/posts/show/2335
UPDATE: O kbmurata comentou no twitter que algum server/client de ssh pode reclamar das permissões da pasta .ssh, se isso acontecer, rode:
1
| |
Sempre usei os bots do Google para o gtalk, mas percebi que os resultados que eles retornam são bem diferentes da página de tradução.
Então fiz uma página bem simples que usa a Language API do Google para traduzir textos do Inglês para o Português e do Português para o Inglês, sem todas aquelas opções de linguas que a página deles oferece.
Para você que tem interesse em saber como funciona traduzir textos com a Language API do Google, veja como é fácil:
1
| |
e depois
1 2 3 4 5 | |
Há tempos atrás desenvolvi uma pequena aplicação usando Shoes, e ontem resolvi atualizá-la, mudei um pouco a aparência e melhorei o suporte a pronúncia.
Caso tenha interesse em usar, você pode baixar o projeto do github: http://github.com/rafaelss/shoes-translator
Falando um pouco agora sobre o Shoes, me parece que após o sumiço do _why a coisas não vão tão bem, o projeto amadureceu muito pouco, muita coisa básica ainda é complicado de se fazer, impedindo um pouco que aplicações mais profissionais sejam feitas rodando sobre o framework.
Quando desenvolvi o shoes-translator na primeira vez, eu levava mais fé no projeto, acreditava que seria um concorrente de peso para os toolkits atuais, mas agora, voltando a mexer na código e buscando referências na internet para fazer as alterações, percebi que o Shoes ainda precisa de muito, mas muito trabalho para poder ter crédito suficiente e ser usado para fazer software de verdade.
UPDATE: O @kbmurata postou no twitter que o objetivo do Shoes é ser usado para o aprendizado de forma divertida, de qualquer forma, se você quiser começar um projeto usando Shoes, pense bem que tipo de projeto você está desenvolvendo, não pense em nada muito maior que um "tradutor de sapatos"
De ontem pra hoje perdi um bom tempo tentando compilar um passenger mais novo em um servidor que tem um /tmp de apenas 1MB (eu ainda preciso descobrir porque isso).
A solução é simples até, basta setar a var TMPDIR com o path de um outro diretório qualquer, mais ou menos assim:
1
| |
Detalhe: eu estava acostumado a setar variáveis ao executar um comando colocando ela na frente do comando, mas com o sudo isso não funciona. No help do sudo diz que deve ficar ali no meio
1
| |
O Tailor lançou a idéia no twitter e eu apoiei, então, semana que vem, #horaextra na Cidade Baixa, em Porto Alegre, mais exatamente no Copão
A idéia é juntar um monte (ou não) de nerds pra falar de trabalho, tecnologia, frameworks, programação, enfim, tudo o que a gente mais gosta
Então, segunda-feira, 19:30, Copão. Aparece lá!
O framework MVC da Microsoft usa um determinado objeto para definir qual tipo de resultado/output a action executada deve retornar. São eles:
ContentResult- Pode ser usado para retornar textos simples.EmptyResult- Esse serve para retornar resultados em branco, quando quiser que o output seja vazio.HttpUnauthorizedResult- Usado quando o usuário não tem permissão para executar a action. Retorna o 401 como status da requisição.JsonResult- Serializa um objeto em formato JSON, bom para ser usando em requisições AJAX.RedirectResult- Resultado usado para redirecionamentos.RedirectToRouteResult- Também usado para redirecionamentos, mas a URL está ligada a uma rota.-
ViewResultBase- Classe abstrata, usada para renderizar HTMLs.PartialViewResult- EstendeViewResultBasepara renderizar as views e seus HTMLs.
-
BinaryResult- Classe abstrata usada para resultados binários.BinaryStreamResult- EstendeBinaryResult, pode ser usado para escrever imagens direto no stream do resutado.
Porém, em alguns casos, retornar um texto simples, ou um JSON pequeninho, é meio chato. Considere o código abaixo:
1 2 3 4 | |
Isso poderia ser mais simples não? Porém, a classe JsonResult, e nenhuma outra ActionResult aceita parâmetros no construtor. Por isso criei duas classes que podem ser usadas como ActionResult, para simplificar essa tarefa. Elas devem ser usadas assim:
1 2 3 4 | |
e
1
| |
Pronto, agora é hora de refatorar código. :)
UPDATE: Conforme o Guilherme comentou ali embaixo, o ASP.NET MVC tem um método que já simplifica as coisas.
1 2 3 4 | |
e
1
| |
Hoje estava verificando um bug em um projeto, que acontecia somente no Safari, tanto no MacOS, quanto no Windows, e descobri que o problema era a forma como eu estava definindo o elemento HTML envolvido na história.
O expressão que eu estava usando era a seguinte:
1
| |
No Safari sempre me retornava 0, já no Firefox e Internet Explorer, retorna 1, que era para ser o valor certo no caso. Analisando como o input estava definido eu descobri o problema, ele estava definido assim:
1
| |
Resumindo:
O Safari não acha elementos onde o atributo filtrado não esteja presente no HTML. (Estou usando a versão 1.3.2 do jQuery e 4.0 (503.17) do Safari, no Windows, mas reportaram o problema no Mac também)
Você desenvolve uma biblioteca de utilitários para facilitar a vida dos outros desenvolvedores da empresa, porém algumas vezes é necessário refatorar códigos, criando/renomeando/apagando alguns métodos. Obviamente você não pode sair mudando tudo, existe código "antigo" usando a sua "lib".
Existe um atributo no C# que permite que você marque código como deprecated,
é o Obsolete, muito útil e fácil de usar.
1 2 3 4 | |
No exemplo acima quero que os desenvolvedores usem a versão que recebe um integer como parâmetro,
e não mais a versão com string.
Você ainda pode dizer que é para o compilador gerar um erro ao compilar o código,
passando true como segundo parâmetro do atributo.
1 2 3 4 | |
Muitas vezes quando configuramos um servidor para hospedar sites para diferentes usuários, a primeira coisa que pensamos é em colocar os sites de cada usuário na pasta home do mesmo, mas para isso funcionar corretamente precisamos dar permissão para o Apache ler a home de cada usuário. A solução que tenho usado é dar a seguinte permissão na pasta do usuário
1
| |
Depois disso todos os "forbidden" desaparecem :)
Se você estiver com problemas para instalar o RMagick no Ubuntu usando apt-get talvez essa solução possa ajudar. Primeiro, limpe os pacotes com "problemas":
1
| |
depois instale os seguintes pacotes:
1
| |
depois disso é só instalar a gem:
1
| |
dica retirada daqui
Se você tem problemas de conexão com SQL Server 2005 pelo PHP, tente usar essa versão (2000.80.194.0) da ntwdblib. Coloque esse arquivo na raiz da instalação do seu PHP, substituindo a versão existente, e reinicie o servidor web.
Uma coisa que eu sempre precisava e nunca me lembrava como fazer era descobrir qual a distro que eu estava usando no momento, como muitas vezes precisei mexer com os mais variados servidores, algumas vezes precisava dessa informação, e hoje achei o jeito mais fácil de fazer isso
1
| |
No meu micro aparece
Liquid error: ClassNotFound: no lexer for alias 'txt' found
No do meu colega
Liquid error: ClassNotFound: no lexer for alias 'txt' found
Achei essa dica aqui e estou documentando aqui pra não esquecer mais :)
Hoje quando li o feed de comentários do blog do TaQ (re)apareceu uma dica que ele deu há um bom tempo, sobre usar uma única instância do Vim para editar arquivos, acho muito chato ter que abrir muitos editores.
Porém a dica que ele deu não funcionou para mim, apenas esta dos comentários, que ao invés de usar um alias, usa uma função.
1 2 3 4 | |
Eu mudei o nome para edit, acho mais fácil, mas fica a critério de cada um :)
Link do codigo original: http://pastebin.com/f7a69dcd7
Vi no blog do Luiz Rocha hoje um meme que rolou há um bom tempo atrás e resolvi fazer também.
1 2 3 4 5 6 7 8 9 10 11 | |
Minha única surpresa foi o braid, considerando que conheci ele faz uma semana e que só utilizo ele em um projeto.
UPDATE: O controle de versão do GAE não é muito "esperto", acabei mudando de micro e perdi tudo. Então, o site não existe mais.
No começo do mês recebi a liberação para usar o Google App Engine, foi o que faltava para eu dar uma brincada com Python.
Onde trabalho, toda a tarde rola de alguém ir no mercado comprar uns refrigerantes, mas todo dia era uma "briga" para ver quem ia. Para resolver isso, criamos página simples em PHP que sorteava quem naquele dia ia fazer as compras.
Depois que a minha conta foi liberada, fiquei um bom tempo pensando o que eu poderia fazer para usá-la, e então o Joel deu a idéia, fazer aquela "págininha" em Python e disponibilizar no Google App Engine.
http://eoescolhidofoi.appspot.com/
É simplesmente fantástica a facilidade de se criar uma aplicação e fazer o deploy dela no Google App Engine, o fato de não ter que se preocupar com banco de dados influencia bastante, basta definir modelos no próprio código, pensar apenas em objetos.
Depois dessa primeira eu já criei mais duas, uma está pronta, mas estou testando ainda, a outra está a caminho, mas será para a empresa que trabalho.
Depois de uma busca insana por um editor de texto acabei escolhendo o Vim, estou usando ele direto faz uma semana e estou me adaptando bem, apesar de algumas coisas me deixarem meio perdido (teclas de atalho principalmente).
Eu estava usando o Vim no console, com um tema com fundo escuro, e como estou usando o computador em um lugar muito claro, o reflexo que a minha tela emite fazia com que eu forçasse muito a visão para enxergar o código. Foi então que eu achei isto, um tema usando as cores do Github, instalei e ficou muito bom!
Um detalhe apenas é que a cor do fundo não é a mesma, nos comentários o Felipe Contreras dá a cor certa. Como não achei nenhum fork com a correção, eu mesmo o fiz.
Se você achar que alguma outra cor não está correta, você sabe, fork e pull request :)
Eu sei, eu sei, Rails Summit já foi faz tempo, mas só agora consegui postar alguma coisa aqui no blog.
O evento estava muito bom, muito motivador, palestras como a do Obie Fernandez, do Vinícius Teles e do Chad Fowler me fizeram mudar alguns aspectos na minha vida profissional (motivo pelo qual esse blog ficou um pouco abandonado), estou focando mais em desenvolver alguma coisa do que simplesmente assistir a tudo de braços cruzados. Gmail só o essencial e Google Reader e Twitter são raramente abertos em casa.
No momento networking do evento, reencontrei o Jony e o Tailor, que tinha conhecido no FISL, e conheci mais uma galera legal lá, citando alguns: Júlio Monteiro, Henry Hamon, Evandro Dutra, Rafael Lima, Henrique Bastos, Thiago Pradi, Davis Cabral e mais alguns outros que não me lembro o nome.
Enfim, espero que o ano que vem tenhamos outro evento neste mesmo nível (ou até melhor), que com certeza eu estarei lá.
Semana passada eu resolvi mudar o domínio do blog, usar algo mais pessoal, e acabei escolhendo http://rafaelss.com, mais simples, mais curto, tem meu nome, enfim, muito melhor :)
Mas com isso veio a necessidade de redirecionar do domínio antigo, http://www.joeh.com.br, para o novo.
Isso é muito fácil.
Liquid error: ClassNotFound: no lexer for alias 'conf' found
Com isso todos os links que apontam para o domínio velho são redirecionados para o novo, com o permanent ali as buscas se entendem, a indexação não é afetada, e tudo continua funcionando normalmente como era antes.
É impressionante como alguns desenvolvedores muitas vezes não procuram uma forma mais simples de fazer certas tarefas do dia-a-dia, um exemplo clássico: Deixar apenas números em uma string, nesse caso, o número de uma agência bancária.
Primeiro a forma que vejo normalmente (em C#)
1 2 3 4 | |
Forma simplificada (C# também)
1
| |
Não é muito mais simples? Basta procurar! ;)
Posts
Scrappy Ruby tips and techniques for the young at heart!
This is the first article in a series where I’ll implement a Unix shell in pure Ruby code.
Since the release of Heroku’s Cedar platform they’ve opened up the opportunity for users to run web applications on any stack. Using something called a buildpack we can describe a template for deploying any kind of application.
Story.find_by_legacy_id(legacy_id) or raise ActiveRecord::RecordNotFound
You’re doing it really wrong, use the bang version instead, like that: Story.find_by_legacy_id!(legacy_id)
The exception will automatically raised and you don’t need to pollute your code :)
In order to get your login shell to execute the script (without forking) you have to use the “.” command (for the Bourne or Korn shells) or the “source” command (for the C shell). I.e. you type
. myscript
You can use free tool:
free -m
or
cat /proc/meminfo
but showing info in KB
http://www.rampant-books.com/t_linux_8_system_buffers_ram.htm
Complementing this post from Ruby Quicktips
If you want to ensure that a local variable has a value, you can do so:
>> somevar
NameError: undefined local variable or method `somevar' for main:Object
from (irb):1
>> somevar = somevar || "somevalue"
=> "somevalue"
but if you try to set another variable, using a value of a variable that may not exists, you will get an error:
>> somevar
NameError: undefined local variable or method `somevar' for main:Object
from (irb):1
>> someothervar = somevar || "somevalue"
NameError: undefined local variable or method `somevar' for main:Object
from (irb):2
If you need to find out what commit a word/phrase was removed, you may try this:
git log --pretty=oneline -S'my_method_name'
This command can be used to find any piece of code, removed or not.
By default git stash show shows only a simple diff, to show the full version, use -u parameter, like this:
git stash show -u
if you are trying to use thin with a rails app and is getting this:
$ thin start
>> Using rails adapter
Missing the Rails 2.3.5 gem. Please `gem install -v=2.3.5 rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.
so, all you need to do is uninstall rack 1.1.0. I am using rack 1.0.1 now it’s working very nice.
source: http://osdir.com/ml/RubyonRailsTalk/2010-01/msg01970.html
PS: Could someone, please, show me a theme that no breaks with long lines of code? ¬¬
ActiveSupport adds some methods to convert strings into dates/times, it’s very nice, take a look.
Instead:
>> Date.parse('2010-01-12')
=> Tue, 12 Jan 2010
You can do:
>> '2010-01-12'.to_date
=> Tue, 12 Jan 2010
It’s very more intuitive and readable!
http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Conversions.html
From my co-worker Daniel Takashi
git log --pretty=format:'%H : %s' --topo-order --graph
… is a bit different from switch in other languages, take a look
>> case 1
>> when 1
>> when 2
>> when 3
>> '1, 2 or 3'
>> else
?> 'higher than 3'
>> end
=> nil
>> case 1
>> when 1, 2, 3
>> '1, 2 or 3'
>> else
?> 'higher than 3'
>> end
=> "1, 2 or 3"
Do you want the process ID? Simple!
rake ts:dd &
echo $! > log/delta.pid
Please, don’t use sleep! Use setTimeout, sleep function turn browser unresponsive, and it’s very annoying.
setTimeout(function() { alert('delayed alert') }, 2000);
If you want not call alert, for any reason, before 2s, you can use clearTimeout.
var timer = setTimeout(function() { alert('delayed alert') }, 2000);
// ...
// ...
if(foo) {
clearTimeout(timer);
}
I like thin and I use it to run all my projects.
Rails:
script/server thin
script/server thin -e environment -p 1234
Sinatra:
thin -R config.ru -D start
Posts
class MyDecorator
attr_accessor :view_context
def form(&block)
view_context.form_for(TheModel.new, &block)
end
endThe Form
server {
listen 8081;
server_name localhost;
location /site {
internal;
postgres_escape $api_key $arg_api_key;
postgres_pass database;
postgres_query "SELECT id FROM sites WHERE api_key = $api_key";
postgres_rewrite no_rows 403;
postgres_output value;
}
location /exist {
internal;
postgres_escape $path $arg_path;
postgres_pass database;
postgres_query "SELECT id FROM templates WHERE site_id = $arg_site_id AND path = $path";
postgres_rewrite no_rows 404;
postgres_output value;
}
location /insert {
internal;
set_unescape_uri $body $arg_body;
postgres_escape $path $arg_path;
postgres_escape $body;
postgres_pass database;
postgres_query "INSERT INTO templates (site_id, path, body, created_at, updated_at) VALUES ($arg_site_id, $path, $body, NOW(), NOW()) RETURNING 'id'";
postgres_rewrite no_changes 422;
postgres_output none;
}
location /update {
internal;
set_unescape_uri $body $arg_body;
postgres_escape $body;
postgres_pass database;
postgres_query "UPDATE templates SET body = $body, updated_at = NOW() WHERE id = $arg_id";
postgres_rewrite no_changes 422;
postgres_output none;
}
location /delete {
internal;
postgres_pass database;
postgres_query "DELETE FROM templates WHERE id = $arg_id";
postgres_rewrite no_changes 404;
postgres_output none;
}
location / {
proxy_pass http://localhost:8082;
proxy_set_header X-Real-IP $remote_addr;
echo $request_body;
}
location ~ /(.+) {
lua_need_request_body on;
content_by_lua '
if ngx.var.arg_api_key then
res = ngx.location.capture("/site", { args = { api_key = ngx.var.arg_api_key } })
if res.status == ngx.HTTP_OK then
local site_id = res.body
local matches = ngx.re.match(ngx.var.echo_request_uri, "^\/([^\?]+)")
res2 = ngx.location.capture("/exist", { args = { site_id = site_id, path = matches[1] } })
local template_id = res2.body
if ngx.var.echo_request_method == "DELETE" then
if res2.status == ngx.HTTP_NOT_FOUND then
ngx.exit(res2.status)
else
res3 = ngx.location.capture("/delete", { args = { id = template_id } })
end
elseif ngx.var.echo_request_method == "PUT" then
if res2.status == ngx.HTTP_NOT_FOUND then
res3 = ngx.location.capture("/insert", { args = { site_id = site_id, path = matches[1], body = ngx.var.request_body } })
elseif res2.status == ngx.HTTP_OK then
res3 = ngx.location.capture("/update", { args = { id = template_id, body = ngx.var.request_body } })
else
ngx.exit(res2.status)
end
end
ngx.exit(res3.status)
else
ngx.exit(res.status)
end
else
ngx.exit(ngx.HTTP_FORBIDDEN)
end
';
}
}version="1.2.0" pcre_version="8.30" rm -rf nginx-$version && \ wget http://nginx.org/download/nginx-$version.tar.gz && \ tar -zxvf nginx-$version.tar.gz && \ cd nginx-$version/contrib && \ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-$pcre_version.tar.gz && \ tar -zxvf pcre-$pcre_version.tar.gz && \ cd pcre-$pcre_version && \ ./configure && make && \ cd ../../ && \ mkdir ext && \ cd ext && \ git clone git://github.com/simpl/ngx_devel_kit.git && \ git clone git://github.com/FRiCKLE/ngx_postgres.git && \ git clone git://github.com/agentzh/set-misc-nginx-module.git && \ git clone git://github.com/agentzh/nginx-eval-module.git && \ cd .. && \ ./configure --prefix=/opt/nginx --with-http_ssl_module --with-pcre=contrib/pcre-$pcre_version \ --add-module=ext/ngx_devel_kit \ --add-module=ext/ngx_postgres \ --add-module=ext/set-misc-nginx-module \ --add-module=ext/nginx-eval-module && \ make && \ make install && \ rm ../nginx-$version.tar.gz
## Requirements * postgresql ## Installation `curl https://raw.github.com/gist/2312669/2bc13aa4c0c9a93b35d19f373d82e611eff9df61/build.sh | sh`
require "nokogiri" xmldoc = Nokogiri::XML(File.read(ARGV[0]), nil, nil, Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NOCDATA | Nokogiri::XML::ParseOptions::STRICT) print xmldoc.at(ARGV[1]).canonicalize
$ ab -n 5 -c 5 http://127.0.0.1:3000/
This is ApacheBench, Version 2.3
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient).....done
Server Software: thin
Server Hostname: 127.0.0.1
Server Port: 3000
Document Path: /
Document Length: 6 bytes
Concurrency Level: 5
Time taken for tests: 25.009 seconds
Complete requests: 5
Failed requests: 0
Write errors: 0
Total transferred: 575 bytes
HTML transferred: 30 bytes
Requests per second: 0.20 [#/sec] (mean)
Time per request: 25008.950 [ms] (mean)
Time per request: 5001.790 [ms] (mean, across all concurrent requests)
Transfer rate: 0.02 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 0
Processing: 25009 25009 0.0 25009 25009
Waiting: 25008 25009 0.0 25009 25009
Total: 25009 25009 0.1 25009 25009
Percentage of the requests served within a certain time (ms)
50% 25009
66% 25009
75% 25009
80% 25009
90% 25009
95% 25009
98% 25009
99% 25009
100% 25009 (longest request)run proc do |env|
puts Time.now
sleep 5
[200, { "Content-type" => "text/plain" }, ["Hello!"]]
end
$ thin -R config.ru start >> Thin web server (v1.3.1 codename Triple Espresso) >> Maximum connections set to 1024 >> Listening on 0.0.0.0:3000, CTRL+C to stop 2012-02-29 00:02:03 -0300 2012-02-29 00:02:08 -0300 2012-02-29 00:02:13 -0300 2012-02-29 00:02:18 -0300 2012-02-29 00:02:23 -0300
$ time ruby script/test_recurrence.rb bundle exec ruby script/test_recurrence.rb real 0m9.903s user 0m7.250s sys 0m1.205s real 0m8.395s user 0m7.157s sys 0m1.101s real 0m8.879s user 0m7.265s sys 0m1.141s
$ time ruby script/test_recurrence.rb bundle exec ruby script/test_recurrence.rb real 0m5.156s user 0m3.961s sys 0m0.957s real 0m5.142s user 0m3.995s sys 0m0.951s real 0m4.910s user 0m3.920s sys 0m0.930s
$ ruby /tmp/test_mock.rb true true
require "rspec/mocks" include RSpec::Mocks::Methods class MyClass; end MyClass.should_receive(:my_method).never puts MyClass.respond_to?(:my_method) class MyOtherClass; end MyOtherClass.should_not_receive(:my_method) puts MyClass.respond_to?(:my_method)
ruby-1.9.2-p290 :001 > Date.today => Sun, 04 Sep 2011 ruby-1.9.2-p290 :002 > Date.tomorrow => Mon, 05 Sep 2011
ruby-1.9.2-p290 :008 > Date.today => Sun, 04 Sep 2011 ruby-1.9.2-p290 :009 > Date.tomorrow => Tue, 06 Sep 2011
## Countdown - Numbers Round
To run the code you must follow the commands below:
gem install riot # or sudo gem intall riot
git clone git://gist.github.com/1193748.git
cd 1193748
ruby -I. countdown_test.rb
I choose use [riot](https://rubygems.org/gems/riot) as test framework. I'm using it in some small projects
and I'm liking it a lot.
About the code, I tried to build it using the simplest way instead of make it too complex and hard to understand.
I think it's not finding all possible results for all input sources. An example of this is the last test, as I commented there,
the closest result was not what the test is checking.
Also, I put a timeout of 30 seconds, like the original game. I don't know if I should do this, but I tried to keep in the same format
as it's showed on TV :)
class Countdown
include Timeout
def self.start(source, target)
cached_results = []
source.sort_by! { |n| -n }
source.each do |n|
source.each do |i|
cached_results require "rubygems"
require "timeout"
require "riot"
require "active_support/core_ext/enumerable"
require "countdown"
context "Countdown" do
context "round #1" do
setup { Countdown.start([ 100, 5, 5, 2, 6, 8 ], 522) }
asserts_topic.equals(522)
end
context "round #2" do
setup { Countdown.start([ 25, 7, 5, 6, 6, 9 ], 814) }
asserts_topic.equals(814)
end
context "round #3" do
setup { Countdown.start([ 7, 8, 2, 5, 8, 4 ], 622) }
asserts_topic.equals(622)
end
context "round #4" do
setup { Countdown.start([ 75, 100, 5, 2, 9, 4 ], 612) }
asserts_topic.equals(612)
end
context "round #4" do
setup { Countdown.start([ 100, 75, 50, 25, 2, 10 ], 976) }
asserts_topic.equals(976)
end
context "round #5" do
setup { Countdown.start([ 7, 7, 1, 2, 9, 1 ], 220) }
asserts_topic.equals(220)
end
context "round #6" do
setup { Countdown.start([ 3, 5, 5, 4, 1, 7 ], 878) }
asserts_topic.equals(878)
end
context "round #7" do
setup { Countdown.start([ 4, 8, 50, 1, 4, 8 ], 596) }
asserts_topic.equals(596)
end
context "round #8" do
setup { Countdown.start([ 75, 2, 8, 5, 10, 10 ], 926) }
asserts_topic.equals(926)
end
context "round #9" do
setup { Countdown.start([ 3, 51, 17, 29, 7, 71 ], 93475) }
asserts_topic.equals(93429) # the closest result is 93478, but I can't figure out how get this result
end
end
function _bundle_exec() {
if [ -e Gemfile ]; then
grep -q "$1" "Gemfile.lock"
if [[ "$1" == "ruby" || $? -eq 0 ]]; then
echo "bundle exec $@"
bundle exec $@
return
fi
fi
$@
}
for cmd in ruby rails rake rspec
do
alias $cmd="_bundle_exec $cmd"
done
require "rubygems"
require "typhoeus"
require "awesome_print"
def run(follow)
request = Typhoeus::Request.new("http://www.google.com", :method => :get)
request.follow_location = follow
hydra = Typhoeus::Hydra.new
hydra.queue(request)
hydra.run
response = request.response
ap "follow location: #{follow}"
ap response.headers_hash
end
##################
ap "AFTER b8840c5"
run(false)
run(true)
###################
ap "BEFORE b8840c5"
module Typhoeus
class Response
def headers_hash
headers.split("\n").map {|o| o.strip}.inject({}) do |hash, o|
if o.empty?
hash
else
o = o.split(":")
hash[o.first.strip] = o.last ? o.last.strip : nil
hash
end
end
end
end
end
run(false)
run(true)
$ ruby typhoeus_headers.rb
"AFTER b8840c5"
"follow location: false"
{
"Location" => "http://www.google.com.br/",
"Cache-Control" => "private",
"Content-Type" => "text/html; charset=UTF-8",
"Set-Cookie" => "PREF=ID=e67e601bcb3fc662:FF=0:TM=1309365035:LM=1309365035:S=d90nwXjW6KthL-wJ; expires=Fri, 28-Jun-2013 16:30:35 GMT; path=/; domain=.google.com",
"Date" => "Wed, 29 Jun 2011 16:30:35 GMT",
"Server" => "gws",
"Content-Length" => "222",
"X-Xss-Protection" => "1; mode=block"
}
"follow location: true"
{
"Location" => "http://www.google.com.br/",
"Cache-Control" => [
[0] "private",
[1] "private, max-age=0"
],
"Content-Type" => [
[0] "text/html; charset=UTF-8",
[1] "text/html; charset=ISO-8859-1"
],
"Set-Cookie" => [
[0] "PREF=ID=2c66cb3d0cf225ea:FF=0:TM=1309365037:LM=1309365037:S=99q4Av29cJo5uetM; expires=Fri, 28-Jun-2013 16:30:37 GMT; path=/; domain=.google.com",
[1] "NID=48=KFHHKThDn2qEPOIgsTQANfAQi14af565bAZn0JVK3YgVWHQDNKoJjAjWX9EkrscTSuUrXgbycJ3JuF_HCnyqWkdWmumXkXHYfNSPuYZhfq9FdZ79ZH7ZEDbwKvkVHaA_; expires=Thu, 29-Dec-2011 16:30:37 GMT; path=/; domain=.google.com; HttpOnly",
[2] "PREF=ID=1725c9fb5ecbc8d5:FF=0:TM=1309365038:LM=1309365038:S=lM_sXhUl5r1K561i; expires=Fri, 28-Jun-2013 16:30:38 GMT; path=/; domain=.google.com.br",
[3] "NID=48=Br0VibZQhHJoQc5Znkg8Ew-UvBRUeyhKENHPUn7T5gYQ6-NWwJ7437FoqzkSCf9G2JeBpshEHFAVxBFqg_PGOorp3dmoox_CpakVnN8y5qOzYxxQ_azkROe9RZHlVWNA; expires=Thu, 29-Dec-2011 16:30:38 GMT; path=/; domain=.google.com.br; HttpOnly"
],
"Date" => [
[0] "Wed, 29 Jun 2011 16:30:37 GMT",
[1] "Wed, 29 Jun 2011 16:30:38 GMT"
],
"Server" => [
[0] "gws",
[1] "gws"
],
"Content-Length" => "222",
"X-Xss-Protection" => [
[0] "1; mode=block",
[1] "1; mode=block"
],
"Expires" => "-1",
"Transfer-Encoding" => "chunked"
}
"BEFORE b8840c5"
"follow location: false"
{
"HTTP/1.1 302 Found" => "HTTP/1.1 302 Found",
"Location" => "//www.google.com.br/",
"Cache-Control" => "private",
"Content-Type" => "text/html; charset=UTF-8",
"Set-Cookie" => "44 GMT; path=/; domain=.google.com",
"Date" => "44 GMT",
"Server" => "gws",
"Content-Length" => "222",
"X-XSS-Protection" => "1; mode=block"
}
"follow location: true"
{
"HTTP/1.1 302 Found" => "HTTP/1.1 302 Found",
"Location" => "//www.google.com.br/",
"Cache-Control" => "private, max-age=0",
"Content-Type" => "text/html; charset=ISO-8859-1",
"Set-Cookie" => "00 GMT; path=/; domain=.google.com.br; HttpOnly",
"Date" => "00 GMT",
"Server" => "gws",
"Content-Length" => "222",
"X-XSS-Protection" => "1; mode=block",
"HTTP/1.1 200 OK" => "HTTP/1.1 200 OK",
"Expires" => "-1",
"Transfer-Encoding" => "chunked"
}module RubyExt
module Boolean
def bool?
[ true, false ].include?(self)
end
end
end
::Object.__send__ :include, RubyExt::Boolean
OpenSSL::SSL::SSLError:
SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failedbefore_filter :load_comments, :only => [ :index, :create ]
def index
end
def create
@comment = Comment.new(params[:comment])
if @comment.save
render 'index'
end
end
private
def load_comments
@comments = @commentable.comments
end
def index
@trainers = if params[:franchise_id]
Trainer.where(:franchise_id => params[:franchise_id]).all
else
Trainer.all
end
end
require 'mechanize'
require 'sinatra'
get '/:psuid' do
find_name params[:psuid]
end
def find_name(psuid)
page = Mechanize.new.get('http://psu.edu/ph')
search_result = page.form_with(:name => 'search') do |search|
search.uid = psuid
end.submit
word = search_result.parser.at('html body form table tr td b').text
word[21, word.length].split(" ").map do |n|
n.downcase.capitalize
end.join(" ")
rescue
"There was an error trying to fetch ID: '#{psuid}'"
end
models
------
class Bookmark
referenced_in :user
end
class User
references_many :bookmarks, :dependent => :destroy
end
index.slim
----------
@bookmarks.each do |bookmark|
...
= bookmark.user.username
...
beta.20 log
-----------
(repeated at least 50 times)
truffls_development['bookmarks'].find({"$or"=>[{:private=>false}, {:private=>true, :user_id=>BSON::ObjectId('4d16ae21a46a2d600b000005')}]}, {}).limit(50).sort([[:created_at, :desc], [:updated_at, :desc]])
truffls_development['users'].find({:_id=>BSON::ObjectId('4d16ae21a46a2d600b000005')}, {}).limit(-1)
beta.20 response time
---------------------
Completed 200 OK in 291ms (Views: 276.6ms)
rc.4 log
--------
(repeated at least 50 times)
truffls_development['bookmarks'].find({"$or"=>[{:private=>false}, {:private=>true, :user_id=>BSON::ObjectId('4d16ae21a46a2d600b000005')}]}, {}).limit(50).sort([[:created_at, :desc], [:updated_at, :desc]])
truffls_development['users'].find({:_id=>BSON::ObjectId('4d16ae21a46a2d600b000005')}, {}).limit(-1)
truffls_development['bookmarks'].find({"user_id"=>BSON::ObjectId('4d16ae21a46a2d600b000005')}, {})
MONGODB cursor.refresh() for cursor 6223321165071467073
rc.4 response time
------------------
Completed 200 OK in 14728ms (Views: 14714.9ms)
- content_for :no_right do No
- unless no_right = yield(:no_right)
= render :partial => "partials/somefile", :locals => {:users => @users}console.log("hello world!");print "hello world!"
print "hello world!"
puts "hello world!"
$ ./run.sh node === hello world! real 0m0.067s user 0m0.042s sys 0m0.020s lua ==== hello world! real 0m0.004s user 0m0.001s sys 0m0.002s php === hello world! real 0m0.059s user 0m0.037s sys 0m0.014s perl === hello world! real 0m0.013s user 0m0.003s sys 0m0.005s ruby === hello world! real 0m0.014s user 0m0.007s sys 0m0.005s
#!/usr/bin/env bash echo "node ===" time node hello_world.js echo "" echo "lua ====" time lua hello_world.lua echo "" echo "php ===" time php hello_world.php echo "" echo "perl ===" time perl hello_world.pl echo "" echo "ruby ===" time ruby hello_world.rb echo ""
#!/usr/bin/env sh # 1. save this file in /usr/local/bin/htmlsite # 2. change default path (~/projects) to whatever you want # 3. then execute: # $ chmod +x /usr/local/bin/htmlsite # now you're able to execute: htmlsite git clone http://github.com/joelsouza/html5-structure.git ~/projects/$1 cd ~/projects/$1 rm -rf .git
class SpiderController "created_at DESC", :conditions => ["site_id = ? AND created_at site, :status => response.code)
end
end
end
end
function _git_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
function _rvm_gemset {
rvm gemset name | sed -e '/^$/d' -e 's/\(.*\)/ \1/'
}
function reload {
source ~/.bash_profile
}
export GREP_OPTIONS="--color=auto"
export GREP_COLOR="4;33"
export CLICOLOR="auto"
export GEM_EDITOR="mate"
CDPATH=".:~:~/projects"
PS1='\n[\[\033[0;37m\]\u] \[\033[0;33m\]\w\a\[\033[0m\]`_rvm_gemset` \[\033[0;32m\]`_git_branch`\e[0m\n\$ '
alias ls="ls -Gh"
alias ll="ls -ls"
alias la="ll -a"
alias unicorn="unicorn --port 3000"
alias git="hub"
alias ss="rails s thin"
alias sc="rails c"
source ~/.gem_completion.sh
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"#
# bash completion support for RubyGems.
#
# Copyright (C) 2010 Nando Vieira
# Distributed under the MIT License.
#
# Usage:
# Just add the following line to your ~/.bash_profile or equivalent.
#
# source ~/.gem_completion.sh
#
# Changelog:
# Jul 14 10 - Added gem list to several commands.
#
_gem ()
{
local cmd=${COMP_WORDS[0]}
local subcmd=${COMP_WORDS[1]}
local cur=${COMP_WORDS[COMP_CWORD]}
COMMANDS="
open build cert check cleanup contents dependency
environment fetch generate_index help install list
lock migrate mirror outdated owner pristine push
query rdoc search server sources space specification
stale tumble uninstall unpack update webhook which yank
"
COMMON_OPTIONS="
--help --verbose --no-verbose --quiet
--config-file --backtrace --debug"
REMOTE_OPTIONS="
--local --remote --both --bulk-threshold
--source --http-proxy --no-http-proxy
--update-sources --no-update-sources
"
BUILD_OPTIONS=$COMMON_OPTIONS
CERT_OPTIONS="
$COMMON_OPTIONS
--add --list --remove --build --certificate
--private-key --sign
"
CHECK_OPTIONS="
$COMMON_OPTIONS
--verify --alien --test --version
"
CLEANUP_OPTIONS="
$COMMON_OPTIONS
--dryrun
"
CONTENTS_OPTIONS="
$COMMON_OPTIONS
--version --all --spec-dir --lib-only
--no-lib-only --prefix --no-prefix
"
DEPENDENCY_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--version --platform --prerelease --no-prerelease
--reverse-dependencies --no-reverse-dependencies --pipe
"
FETCH_OPTIONS="
$COMMON_OPTIONS
--version --platform --bulk-threshold --source
--prerelease --no-prerelease --http-proxy --no-http-proxy
"
GENERATE_INDEX_OPTIONS="
$COMMON_OPTIONS
--directory --legacy --no-legacy --modern --no-modern
--update --rss-gems-host --rss-host --rss-title
"
HELP_OPTIONS="
$COMMON_OPTIONS
$COMMANDS
commands
"
INSTALL_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--platform --version --prerelease --no-prerelease --install-dir
--bindir --rdoc --no-rdoc --ri --no-ri --env-shebang --no-env-shebang
--force --no-force --test --no-test --wrappers --no-wrappers --trust-policy
--ignore-dependencies --include-dependencies --format-executables --no-format-executables
--user-install --no-user-install --development
"
LIST_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--installed --no-installed --version --details --no-details --versions --no-versions
--all --prerelease --no-prerelease
"
LOCK_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--installed --no-installed --details --no-details
--all --prerelease --no-prerelease
"
OUTDATED_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--platform
"
OWNER_OPTIONS="
$COMMON_OPTIONS
--add --remove --http-proxy --no-http-proxy
"
PRISTINE_OPTIONS="
$COMMON_OPTIONS
--all --version
"
PUSH_OPTIONS="
$COMMON_OPTIONS
--http-proxy --no-http-proxy
"
QUERY_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--installed --no-installed --version --name-matches --details --no-details
--versions --no-versions --all --prerelease --no-prerelease
"
RDOC_OPTIONS="
$COMMON_OPTIONS
--all --rdoc --no-rdoc --overwrite --no-overwrite --version
"
SEARCH_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--installed --no-installed --version --details --no-details
--versions --no-versions --all --prerelease --no-prerelease
"
SERVER_OPTIONS="
$COMMON_OPTIONS
--port --dir --daemon --no-daemon --bind
"
SOURCES_OPTIONS="
$COMMON_OPTIONS
--add --list --remote --clear-all --update --http-proxy --no-http-proxy
"
SPECIFICATION_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--version --platform --all --ruby --yaml --marshal
"
UNINSTALL_OPTIONS="
$COMMON_OPTIONS
--all --no-all --ignore-dependencies --no-ignore-dependencies
--executables --no-executables --install-dir --bindir
--user-install --no-user-install --version --platform
"
UNPACK_OPTIONS="
$COMMON_OPTIONS
--target --version
"
UPDATE_OPTIONS="
$COMMON_OPTIONS
$REMOTE_OPTIONS
--system --platform --prerelease --no-prerelease --install-dir
--bindir --rdoc --no-rdoc --ri --no-ri --env-shebang --no-env-shebang
--force --no-force --test --no-test --wrappers --no-wrappers
--trust-policy --ignore-dependencies --include-dependencies
--format-executable --no-format-executable --user-install --no-user-install
--development
"
WEBHOOK_OPTIONS="
$COMMON_OPTIONS
--http-proxy --no-http-proxy --add --remove --fire --global
"
WHICH_OPTIONS="
$COMMON_OPTIONS
--all --no-all --gems-first --no-gems-first
"
YANK_OPTIONS="
$COMMON_OPTIONS
--version --undo
"
case "$subcmd" in
cleanup|contents|dependency|install|list|lock|pristine|search|uninstall|unpack)
local gems=$(gem list | sed 's/(.*)//') ;;
lock|open)
local gems_with_version=$(ruby -rubygems -e 'puts Dir["{#{Gem::SourceIndex.installed_spec_directories.join(",")}}/*.gemspec"].collect {|s| File.basename(s).gsub(/\.gemspec$/, "")}') ;;
esac
case "$subcmd" in
build)
words=$BUILD_OPTIONS ;;
cert)
words=$CERT_OPTIONS ;;
check)
words=$CHECK_OPTIONS ;;
cleanup)
words="$gems $CLEANUP_OPTIONS" ;;
contents)
words="$gems $CONTENTS_OPTIONS" ;;
dependency)
words="$gems $DEPENDENCY_OPTIONS" ;;
environment)
words=$=COMMON_OPTIONS ;;
fetch)
words="$gems $FETCH_OPTIONS" ;;
generate_index)
words=$GENERATE_INDEX_OPTIONS ;;
help)
words=$HELP_OPTIONS ;;
install)
words="$gems $INSTALL_OPTIONS" ;;
list)
words="$gems $LIST_OPTIONS" ;;
lock)
words="$gems_with_version $LOCK_OPTIONS" ;;
migrate)
words=$COMMON_OPTIONS ;;
mirror)
words=$COMMON_OPTIONS ;;
outdated)
words=$OUTDATED_OPTIONS ;;
open)
words="$gems_with_version"
;;
pristine)
words="$gems $PRISTINE_OPTIONS" ;;
push)
words=$PUSH_OPTIONS ;;
query)
words=$QUERY_OPTIONS ;;
rdoc)
words=$RDOC_OPTIONS ;;
search)
words="$gems $SEARCH_OPTIONS" ;;
server)
words=$SERVER_OPTIONS ;;
sources)
words=$SOURCES_OPTIONS ;;
space)
words="$(gem space | sed 's/ //' | sed 's/* //')" ;;
specification)
words=$SPECIFICATION_OPTIONS ;;
stale)
words=$COMMON_OPTIONS ;;
tumble)
words=$COMMON_OPTIONS ;;
uninstall)
words="$gems $UNINSTALL_OPTIONS" ;;
unpack)
words="$gems $UNPACK_OPTIONS" ;;
update)
words=$UPDATE_OPTIONS ;;
webhook)
words=$WEBHOOK_OPTIONS ;;
which)
words=$WHICH_OPTIONS ;;
yank)
words=$YANK_OPTIONS ;;
*)
words=$COMMANDS ;;
esac
COMPREPLY=($(compgen -W "$words" -- $cur))
return 0
}
complete -o default -F _gem gem
#!/usr/bin/env python
# Try to determine how much RAM is currently being used per program.
# Note the per program, not per process. So for example this script
# will report mem used by all httpd process together. In detail it reports:
# sum(all RSS for process instances) + max(shared mem for any process instance)
#
# The shared calculation below will factor out shared text and
# libs etc. within a program, but not between programs. So there
# will always be some overestimation. This will be the same for
# all processes that just use libc for e.g. but more for others
# that use larger shared libs like gnome, kde etc.
# Author: P@draigBrady.com
# V1.0 06 Jul 2005 Initial release
# V1.1 11 Aug 2006 root permission required for accuracy
# V1.2 08 Nov 2006 Add total to output
# Use KiB,MiB,... for units rather than K,M,...
# V1.3 22 Nov 2006 Ignore shared col from /proc/$pid/statm for
# 2.6 kernels up to and including 2.6.9.
# There it represented the total file backed extent
# V1.4 23 Nov 2006 Remove total from output as it's meaningless
# (the shared values overlap with other programs).
# Display the shared column. This extra info is
# useful, especially as it overlaps between programs.
# V1.5 26 Mar 2007 Remove redundant recursion from human()
# V1.6 05 Jun 2007 Also report number of processes with a given name.
# Patch from riccardo.murri@gmail.com
# Notes:
#
# All interpreted programs where the interpreter is started
# by the shell or with env, will be merged to the interpreter
# (as that's what's given to exec). For e.g. all python programs
# starting with "#!/usr/bin/env python" will be grouped under python.
# You can change this by changing comm= to args= below but that will
# have the undesirable affect of splitting up programs started with
# differing parameters (for e.g. mingetty tty[1-6]).
#
# For 2.6 kernels up to and including 2.6.13 and later 2.4 redhat kernels
# (rmap vm without smaps) it can not be accurately determined how many pages
# are shared between processes in general or within a program in our case:
# http://lkml.org/lkml/2005/7/6/250
# A warning is printed if overestimation is possible.
# In addition for 2.6 kernels up to 2.6.9 inclusive, the shared
# value in /proc/$pid/statm is the total file-backed extent of a process.
# We ignore that, introducing more overestimation, again printing a warning.
#
# I don't take account of memory allocated for a program
# by other programs. For e.g. memory used in the X server for
# a program could be determined, but is not.
#
# This script assumes threads are already merged by ps
# TODO:
#
# use ps just to enumerate the pids and names
# so as to remove the race between reading rss and shared values
import sys, os, string
if os.geteuid() != 0:
sys.stderr.write("Sorry, root permission required.\n");
sys.exit(1)
PAGESIZE=os.sysconf("SC_PAGE_SIZE")/1024 #KiB
our_pid=os.getpid()
#(major,minor,release)
def kernel_ver():
kv=open("/proc/sys/kernel/osrelease").readline().split(".")[:3]
for char in "-_":
kv[2]=kv[2].split(char)[0]
return (int(kv[0]), int(kv[1]), int(kv[2]))
kv=kernel_ver()
def getShared(pid):
if os.path.exists("/proc/"+str(pid)+"/smaps"):
shared_lines=[line
for line in open("/proc/"+str(pid)+"/smaps").readlines()
if line.find("Shared")!=-1]
return sum([int(line.split()[1]) for line in shared_lines])
elif (2,6,1) = 1000: #4 digits
num /= 1024.0
power=powers[powers.index(power)+1]
return "%.1f %s" % (num,power)
def cmd_with_count(cmd, count):
if count>1:
return "%s (%u)" % (cmd, count)
else:
return cmd
print " Private + Shared = RAM used\tProgram \n"
for cmd in sort_list:
print "%8sB + %8sB = %8sB\t%s" % (human(cmd[1]-shareds[cmd[0]]), human(shareds[cmd[0]]), human(cmd[1]),
cmd_with_count(cmd[0], count[cmd[0]]))
print "\n Private + Shared = RAM used\tProgram \n"
#Warn of possible inaccuracies
#1 = accurate
#0 = some shared mem not reported
#-1= all shared mem not reported
def shared_val_accurate():
"""http://wiki.apache.org/spamassassin/TopSharedMemoryBug"""
if kv[:2] == (2,4):
if open("/proc/meminfo").read().find("Inact_") == -1:
return 1
return 0
elif kv[:2] == (2,6):
if os.path.exists("/proc/"+str(os.getpid())+"/smaps"):
return 1
if (2,6,1) #!/usr/bin/env ruby
current = `defaults read com.apple.finder AppleShowAllFiles`
current = current.strip == 'TRUE' ? 'FALSE' : 'TRUE'
`defaults write com.apple.finder AppleShowAllFiles #{current}`
`killall Finder`# idéia original em php: http://goncin.wordpress.com/2010/06/21/ditados-populares-em-php/
###############
if tempo.is?(:chuvoso)
cavalinho.recolher
end
################
begin
vencer(@eles)
rescue
juntarSeA(@eles)
end
################
if !@meus_animais.include?(:cachorro)
cacarCom(:gato)
end
################
@espeto = Espeto.new(:pau) if @casa.owner?(:ferreiro)
################
@macacos.each do |macaco|
galho = Galho.new
galho.receber(macaco)
end
################
@seguro.die if @seguro.idade >= 80 # die não existe no ruby nativamente, então esse exemplo ficou nada a ver :)
################
if @filho.parent == :peixe
@filho.type(:peixinho)
end
################
if @rio.peixes.include?(:piranha)
@jacare.estilo_nadar(NADO_COSTAS)
end
################
if @olhos.owner != self
@refresco = @pimenta
@refresco.colocar_em(@olhos)
end
################
@homem.valor *= 2 if @homem.prevenido?
################
Deus.ajudar(@pessoa) if @pessoa.hora_acordou temBoca())
## goto Roma;
## // Milhares de linhas de código depois...
## :Roma
## echo ('Parabéns, você chegou a Roma');
################
@galinha.papo.num_graos += 1 until @galinha.papo.cheio?
################
raise 'Tire a mão daí!!!' if @macaco.idade >= 60 and @macaco.mao.onde_esta == :cumbuca
################
@agua.consistencia = :mole
@pedra.consistencia = :dura
@agua.bater(@pedra) while not @pedra.esta_furada?class Expression include Mongoid::Document field :english end
-
{{#expressions}}
{{#map}}
- {{english}} {{/map}}
{{/expressions}}
class Index
def test_array_of_arrays
template = [
[ {"a" => 1}, {"a" => 2}, {"a" => 3} ],
[ {"a" => 4}, {"a" => 5}, {"a" => 6} ],
[ {"a" => 7}, {"a" => 8}, {"a" => 9} ]
]
}
assert_equal # Static site using Rack (with expire headers and etag support)... great for hosting static sites on Heroku
require "bundler/setup"
require 'rack/contrib'
require 'rack-rewrite'
use Rack::StaticCache, :urls => ['/images','/css','/favicon.ico'], :root => "public"
use Rack::ETag
use Rack::Rewrite do
rewrite '/', '/index.html'
end
run Rack::Directory.new('public')
source "http://rubygems.org" gem 'rack-contrib', :git => 'git://github.com/rack/rack-contrib.git' gem 'rack-rewrite'
# using implicit subject may throw the following error on ruby 1.9.2
# wrong number of arguments (1 for 0)
# /Users/rafael/.rvm/gems/ruby-1.9.2-head/gems/rspec-1.3.0/lib/spec/example/subject.rb:43:in `block in implicit_subject'
# /Users/rafael/.rvm/gems/ruby-1.9.2-head/gems/rspec-1.3.0/lib/spec/example/subject.rb:77:in `instance_eval'
# /Users/rafael/.rvm/gems/ruby-1.9.2-head/gems/rspec-1.3.0/lib/spec/example/subject.rb:77:in `subject'
# /Users/rafael/.rvm/gems/ruby-1.9.2-head/gems/rspec-1.3.0/lib/spec/example/subject.rb:25:in `block (2 levels) in its'
# /Users/rafael/.rvm/gems/ruby-1.9.2-head/gems/rspec-1.3.0/lib/spec/example/subject.rb:91:in `should'
# spec/models/category_spec.rb:17:in `block (3 levels) in '
# seems instance_eval call on line 77 send an argument to lambda returned by implicit_subject, and on ruby 1.9 if you send arguments to a lambda, you need to declare them, the same doesnt happens with proc/Proc.new
# this patch solve this
module Spec
module Example
module Subject
module ExampleGroupMethods
def implicit_subject
# http://github.com/dchelimsky/rspec/blob/master/lib/spec/example/subject.rb#L43
(described_class ? proc {described_class.new} : proc {description_args.first})
end
end
end
end
end# spec/support/matchers/attribute.rb
module AttributeMatchers
Spec::Matchers.define :have_only_attributes do |attributes|
match do |target|
actual_attributes = target.attribute_names.map(&:to_sym)
diff = ((actual_attributes | attributes) - (actual_attributes & attributes))
diff.length == 0
end
end
end
# spec/spec_helper
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |file| require file }
Spec::Runner.configure do |config|
config.include AttributeMatchers
end
# app/models/user.rb
class User "first_name, last_name, email")
end
end
# spec/models/user_spec.rb
User.method_returning_only_one_user.should have_only_attributes([:first_name, :last_name, :email])Profile
Summary
Experience
- Jun 2007 - PresentOwner / Joeh Software
- Oct 2011 - PresentRuby Developer / BlockShopper.comWeb application development using Ruby/Rails/Sinatra and MySQL, related to USA real estate market
- Aug 2011 - PresentRuby Developer / EngageSoftware development using Ruby, Rails, PostgreSQL, jQuery, Heroku and some other cool stuff.
- May 2011 - PresentRuby Developer / SoftaSoftware development using Ruby, Rails, PostgreSQL, jQuery, Heroku and some other cool stuff.
- Jul 2009 - PresentRuby/Rails Developer / BlockShopper.comWeb application development using Ruby/Rails/Sinatra and MySQL related to USA real estate market
- Feb 2009 - PresentDeveloper / BielSystemsDeveloper of web applications with payment management and events management. All apps using Ruby, Ruby on Rails and MySQL.
- Apr 2005 - PresentTech Lead / W3hausDeveloping of base tools for websites and support for development team
- Dec 2004 - PresentJava Developer / Order By!Development of financial software in Java and MS SQL Server, using CORBA to integrate client and server applications. Some of my responsabilities was keep system more eficient, optimizing performance.
- 2003 - PresentProgrammer / Espacio DigitalDevelopment of products to Project Management and Workflow Processes Management using PHP, MySQL, Javascript and XML
- 2001 - PresentPHP Developer / PlanejarI work on development of internal systems and an EAD website as well
Education
-
2007 - 2012Unisinos
Additional Information
Posts
Just in time for Christmas, we have made MariaDB 5.3.3 Release candidate available for download.
Looking at the number of changes and new features, MariaDB 5.3 is probably the biggest milestone release in MySQL history since 5.0:
- Fast sub queries and better optimizer
- Faster and better replication
- NoSQL extensions
- New important types (Microseconds)
MariaDB 5.3 is also important as MariaDB 5.5 is based on this. The merge of the code bases are already completed and as soon as our testing is complete (estimated to a couple of weeks) we will release MariaDB 5.5-beta.
A merry holiday and happy new year to you all!
Once you’ve boarded the Rails train, you just know that every stop along the way is going to be a good time. This release candidate is no different and we’ve packed it with loving goodies without making upgrading a hassle.
Faster dev mode & routing
The most noticeable new feature is that development mode got a ton and a half faster. Inspired by Active Reload, we now only reload classes from files you’ve actually changed. The difference is dramatic on a larger application.
Route recognition also got a bunch faster thanks to the new Journey engine and we made linking much faster as well (especially apparent when you’re having 100+ links on a single page).
Explain queries
We’ve added a quick and easy way to explain quieries generated by ARel. In the console, you can run something like puts Person.active.limit(5).explain and you’ll get the query ARel produces explained (so you can easily see whether its using the right indexes). There’s even a default threshold in development mode where if a query takes more than half a second to run, it’s automatically explained inline—how about that!
Tagged logger
When you’re running a multi-user, multi-account application, it’s a great help to be able to filter the log by who did what. Enter the TaggedLogging wrapper. It works like this:
Logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
Logger.tagged("BCX") { Logger.info "Stuff" } # Logs "[BCX] Stuff"
Logger.tagged("BCX") do
Logger.tagged("Jason") do
Logger.info "Stuff" # Logs "\[BCX\] \[Jason\] Stuff"
end
end
Active Record Store
Key/value stores are great, but it’s not always you want to go the whole honking way just for a little variable-key action. Enter the Active Record Store:
class User < ActiveRecord::Base
store :settings, accessors: [ :color, :homepage ]
end
u = User.new(color: 'black', homepage: '37signals.com')
u.color # Accessor stored attribute
u.settings[:country] = 'Denmark' # Any attribute, even if not specified with an accessor
These are just a few of the highlights. The full release notes detail every loving change.
Given that this is a release candidate, we’re ever so eager to hear your feedback. We hope it’ll be a quick RC phase, but please do spoil that plan by reporting bugs.
As always, you install a release candidate by doing gem install rails --pre.
Derrick Harris:
If you’re wondering what kind of performance and scalability requirements forced these companies to MongoDB, and then to customize it so heavily, here are some statistics:
- Foursquare:
- 15 million users;
- 8 production MongoDB clusters;
- 8 shards of user data;
- 12 shards of check-in data;
- ~250 updates per second on user database, with maximum output of 46 MBps;
- ~80 check-ins per second on check-in database, with maximum output of 45 MBps;
- up to 2,500 HTTP queries per second.
- Wordnik:
- Tens of billions of documents with more always being added;
- more than 20 million REST API calls per day;
- mapping layer supports 35,000 records per second.
- Disney:
- More than 1,400 MongoDB instances (although “your eyes start watering after 30,” Stevens said);
- adding new instances every day, via a custom-built self-service portal, to test, stage and host new games.
Add to these Viber Media numbers:
- 30 million plus registered mobile users
- 18 million active users talking 11 million minutes every day
I have an exclusive interview with Viber Media people queued up for the next days.
Original title and link: MongoDB in Numbers: Foursquare, Wordnik, Disney (NoSQL database©myNoSQL)
PA Design sells die-cut post-its shaped like wristwatches, gummed so they can be joined at the wrist. A cute way to put notes where you're sure to glance at them.
Montre Post It Pense bête [pa-design.com]
| Has your company seen an increase in workplace mobility? Does the cloud really matter for your business? Make sure you’re in the know with Cisco and be prepared for what’s in store. Read, learn, share and discuss the future of the network. | ||
| http://network.cisco.com/ |
via So Much Pun
Related posts:
Giordano Guastala, gestor de TI do D’Incao Instituto de Ensino, sediado em Bauru, procurou o BR-Mac para apresentar um relato da interessantíssima experiência da instituição com o uso de Macs para apoiar os ambientes de aprendizado experimental de ciências e as atividades realizadas em laboratório.
O D’Incao adota o sistema de 1 MacBook por aluno, e todo o seu conceito pedagógico foi pensado diante da tecnologia Apple. Segundo o relato da equipe pedagógica, usando o computador como interface é possível reduzir o tempo de coleta e aumentar a quantidade de dados que podem ser analisados, melhorando a qualidade dos resultados.
Além do Logger Pro, aplicativo especializado na coleta e análise de dados de pesquisa, a escola faz uso extenso das capacidades multimídia oferecidos pelo pacote iLife, da Apple, que permite uma fácil incorporação de mídias por programas científicos de análise de dados, segundo relatado pelo professor de Física da instituição.
O tradicional trio processador de texto, planilha e gerenciador de apresentações também se integra ao conjunto de ferramentas adotadas pela instituição.
Casos práticos de experiências de Física, como o lançamento de um projétil ou a observação do efeito Doppler, podem assim ser complementados com um vídeo editado no iMovie e incorporado aos dados coletados no Logger Pro, por exemplo – tudo servindo para ilustrar e vivenciar a articulação do método científico para o desenvolvimento de soluções.
Completando o pacote tecnológico, todo o processo de relatórios científicos realizados pelos alunos ocorre de forma colaborativa em um Wiki.
Parabéns à equipe e aos alunos do D’Incao Instituto de Ensino, e continuamos sempre atentos a exemplos do bom uso de Macs e iPads em salas de aula brasileiras!
Did you hate the sharp case edging on the MacBook Pro? They’re gone in the new models, instead there is a minor rounding of the newest MacBook Pro series case edges. While this may seem insignificant it’s actually a fairly big deal for anyone who is accustomed to the previous MacBook Pro’s sharp corners, which could be downright uncomfortable after extended use.
If this seems unimportant, keep in mind that some users actually went ahead to file their MacBook edges with nailfiles or otherwise to smooth out the edges themselves (see link, or video below).
In search of a good picture to demonstrate the difference, I stumbled across Marco Arment – the Instapaper guy – mentioning his new MacBook Pro 2011 vs the old one (shown up top), and low and behold he points out the same rounded edges. On the left is the previous MacBook Pro and on the right is the new 2011 model year, the difference is subtle, but apparently makes quite a difference in longterm use.
We’ve received a few emails about this change, the most recent from Rieky W:
I’ve just notice that my brand new macbook pro has a new edge profile. It is not as sharp as previous macbook pro, it’s comfortable to place my wrist now.
I know the sharp edges have prevented some users from upgrading or using the MacBook Pro’s longterm, so the corner adjustment may be important enough to sway a future purchase decision for some individuals, and is therefore worth mentioning.
Oh and here’s the popular video that showed users how to file the edges on an aluminum MacBook Pro themselves:
Thanks for the tip Rieky!
Submitted by: gorsmaster
Posted at: 2011-10-19 06:01:09
See full post and comment: http://9gag.com/gag/378638
OMG! Happy Thursday! I am trying to be totally enthusiastic, but the truth is that I have a cold, so there will be fewer uppercase letters and exclamation points than usual.
Anyway, I want to talk about database connection management in ActiveRecord. I am not too pleased with its current state of affairs. I would like to describe how ActiveRecord connection management works today, how I think it should work, and steps towards fixing the current system.
TL;DR: database connection API in ActiveRecord should be more similar to File API
Thinking in terms of files
It’s convenient to think of our database connection as a file. Dealing with files is very common. When we work with files, the basic sequence goes something like this:
- Open the file
- Do some work on the file handle
- Close the file
We’re very used to doing these steps when dealing with files. Typically our code will look something like this:
File.open('somefile.txt', 'wb') do |fh| # Open the file
fh.write "hello world" # Do some work with the file
end # Close file when block returns
We don’t want to share open files among threads because dealing with synchronization around reading and writing to the file is too difficult (and time consuming). So maybe we’ll store the handle in a thread local or something until we’re ready to close it.
Our basic requirements for dealing with a database connection are essentially the same as when dealing with files. We need to open our database connection, do some work with the connection (send and receive queries), and close the connection. We have these similarities, yet the API for dealing with database connections in ActiveRecord is vastly different. Let’s look at how each of these steps are performed in ActiveRecord today.
Opening a connection
Opening a connection to the database is very easy. First we configure ActiveRecord with the database specification, then we call connection to actually get back a database handle:
ActiveRecord::Base.establish_connection( :adapter => "sqlite", :database => "path/to/dbfile") connection_handle = ActiveRecord::Base.connection
The main difference between this API and the File API is that we’ve separated the connection specification from actually opening the connection. In the case of opening a file, we call open along with a “specification” which includes the file name and how we want to open it. In this case, we’ve separated the two; essentially storing the specification in a global place, then opening the connection later.
This leads to two questions:
- Where is the specification stored?
- When I call
connection, what specification is used?
The answer to the first question can be found by reading the establish_connection method. Specifically if we look at line 63 we’ll find a clue. Since this method is a class method, the call to name returns the class name of the recipient. This name (along with our actual spec) is passed in to the connection handler object. If we jump through a few more layers of indirection, we’ll find that what we have is essentially a one to one mapping of class name to connection specification.
Armed with this information, we can tackle the second question. If we look at the implementation of connection, it calls retrieve_connection on itself, which calls retrieve_connection on the connection handler with itself. A few more method calls later, and we see that each ActiveRecord subclass walks up the inheritance tree looking for a connection:
def retrieve_connection_pool(klass) pool = @connection_pools[klass.name] return pool if pool return nil if ActiveRecord::Base == klass retrieve_connection_pool klass.superclass end
If we read this code carefully, we’ll notice that not only are connection specifications mapped to classes so are database connections!
Why is this bad?
This behavior smells bad to me. The reason is because we’re tightly coupling classes along with database connections when really this relationship doesn’t need to exist.
How can it be improved?
If this tight coupling is removed, the complexity of ActiveRecord can be reduced and at the same time increasing the features available! The way we can reduce this coupling is by passing the connection specification to the method that actually opens the connection. Specifications can be stored on each class as a convenience, but nothing more.
What if opening a connection looked more like this?
spec = ActiveRecord::Base.specificiation ActiveRecord::ConnectionPool.open(spec) do |conn| ... end
We could maintain the current behavior by storing specifications on each class, but eliminate the coupling between connection and class. We would be able to delete all of the code that looks up connections by class hierarchy, and open the doors to having features like this:
spec = database_a ActiveRecord::ConnectionPool.open(spec) do |conn| User.find_all end spec = database_b ActiveRecord::ConnectionPool.open(spec) do |conn| User.find_all end
Working with the connection
Working with our connection should remain the same. We have one place to retrieve our connection and work with it. Woo!
Dealing with thread safety
Sharing open file handles among threads probably isn’t a good idea and the same can be said about open database connections. So how does ActiveRecord keep connections localized to one thread? If we jump through many, many, method calls, we’ll find where the connection is actually checked out of the connection pool. It is here we see how thread safety is handled:
# Retrieve the connection associated with the current thread, or call # #checkout to obtain one if necessary. # # #connection can be called any number of times; the connection is # held in a hash keyed by the thread id. def connection @reserved_connections[current_connection_id] ||= checkout end
A hash is kept where the key is the current_connection_id. The implementation of current_connection_id looks up the current id. If the id isn’t set, it sets it to the object id of the current thread:
def current_connection_id #:nodoc: ActiveRecord::Base.connection_id ||= Thread.current.object_id end
Next we look at the implementation of connection_id to find that it just gets and sets a thread local:
def connection_id Thread.current['ActiveRecord::Base.connection_id'] end def connection_id=(connection_id) Thread.current['ActiveRecord::Base.connection_id'] = connection_id end
These methods ensure that we have a one to one relationship of open connection and thread.
Closing the connection
Finally we reach our last step: closing the connection. How many of you have closed your connection to the database in ActiveRecord? My guess is that it’s very few. I think the reason people don’t typically close their connections with ActiveRecord is twofold. One, you don’t have to because it just does it for you, and two, the API to close a particular connection is pretty convoluted.
So how is the connection closed today? There are two ways, the easy way and the hard way.
The easy way
The easy way is good enough in a non-threaded application. A rack middleware clears out all of the connections at the end of the request. The source for clear_active_connections! is pretty simple. For each connection pool in the system (remember it’s one pool per AR class and connection spec), release that connection:
# Returns any connections in use by the current thread back to the pool,
# and also returns connections to the pool cached by threads that are no
# longer alive.
def clear_active_connections!
@connection_pools.each_value {|pool| pool.release_connection }
end
Each pool releases the connection it has using the current_connection_id (which happens to be the current thread id):
# Signal that the thread is finished with the current connection. # #release_connection releases the connection-thread association # and returns the connection to the pool. def release_connection(with_id = current_connection_id) conn = @reserved_connections.delete(with_id) checkin conn if conn end
Not bad. But what if our system has multiple threads?
The hard way
Believe it or not, the connection pool in ActiveRecord will check in connections in the checkout method. Let me say that again: the checkout method checks in connections and checks out connections. If you’re not facepalming yet, let’s look at a small part of the checkout method:
@queue.wait(@timeout)
if(@checked_out.size < @connections.size)
next
else
clear_stale_cached_connections!
if @size == @checked_out.size
raise ConnectionTimeoutError, "could not obtain a database connection#{" within #{@timeout} seconds" if @timeout}. The max pool size is currently #{@size}; consider increasing it."
end
end
This bit of the checkout method is not called unless our connection pool has become full. First we wait for other threads to check in their connection. While we’re waiting, if other threads checked in their connection, the first branch of the if statement executes, and a connection is returned. If no threads have checked in their connection, we call clear_stale_cached_connections!:
def clear_stale_cached_connections!
keys = @reserved_connections.keys - Thread.list.find_all { |t|
t.alive?
}.map { |thread| thread.object_id }
keys.each do |key|
checkin @reserved_connections[key]
@reserved_connections.delete(key)
end
end
This method walks through every thread in your system, looking for connections that were allocated to threads that no longer exist. Then it checks in connections associated with those dead threads. Since there is really no easy way for users to check in their own connections, this is actually a common code path for systems that use threads.
Why is this bad?
It should be pretty clear why this behavior is bad. Walking through every thread in the system, and asking if it’s alive isn’t very cheap. Even worse is that we’re coupling ourselves to the threading system. We cannot change the connection pool to work with other concurrency solutions (like Fibers) because those solutions may not give us the introspection we need to perform this operation!
But really, this is treating a symptom. The real problem is that checking in connections is too difficult, so people don’t do it.
How can we fix this?
I think the best solution for this is to mimic the File API. If we do this, it will become natural for people dealing with the database connection to actually close the connection.
We should make ActiveRecord::Base.connection consult a thread local. That thread local is set in the rack middleware where the connection is opened. If someone creates a new thread, they must populate that thread local, and close the connection at the end of the thread.
Simplified, our middleware would become something like this:
class ConnectionManagement
def call env
spec = ActiveRecord::Base.spec
connection = ActiveRecord::ConnectionPool.open spec
ActiveRecord::Base.connection = connection
@app.call env
connection.close
end
end
When people create a new thread, it would look something like this:
Thread.new do
spec = ActiveRecord::Base.spec
ActiveRecord::ConnectionPool.open(spec) do |connection|
ActiveRecord::Base.connection = connection
# do some stuff
end
end
What does this buy us?
This buys us two important things: simple connection pool management, and freedom of choice on our concurrency model.
omg the end.
I hope I’ve convinced you that by simply learning to treat our database connection like a file, we can reduce code complexity and at the same time increase the features available. I think I can add this feature to Rails 3.2 and mostly maintain backwards compatibility. I think we can keep 100% backwards compatibility if we add some sort of flag like config.i_suck_and_will_not_close_my_database_connections = true or, config.my_app_is_awesome = true.
Anyway, I’m totally sick and I’ll stop blllluuurrrrggghhhing now.
<3 <3 <3 <3 <3
Shared by PotHix
Caramba! Várias paradas úteis pra caramba.
Nem sempre nos damos conta, mas sempre existe alguém pensando e criando novas ideias para casa. A seguir, você confere algumas ideias muito cristivas feitas para serem usadas na cozinha.
Notas relacionadas:
Submitted by: dronpa
Posted at: 2011-10-16 19:37:33
See full post and comment: http://9gag.com/gag/366979
Batizada de Face Shelving, esta estante para livros é criação do designer Alexi McCarthy.
Na verdade ele teve a ideia em uma conversa com a sua namorada. Da conversa até ter a peça pronta, o projeto demorou um ano.
O mais bacana nisso tudo é que você pode criar diferentes faces só com o simples fato de rearrumar os livros na estante.
Um fato curioso, se olhar na foto da esquerda abaixo, verá que o design tem um livro sobre o Brasil.
Today’s offices, designed by Christian Pottgiesser for PONS + HUOT.
“The project accommodates the headquarters of two companies in Paris – PONS and HUOT – with totally fifteen executives. Consequently the unit has seven individual rooms for each director and one open-space-office for the remaining eight clerks. In addition there is one (divisible) meeting-room, a common recreational room, a kitchen, rest rooms, and, at the special request of the patron, lush vegetation all over the main space.
The base for the construction was a rotten industrial hall built in the late 19th century with a steel framework typical for the period. It is rumoured that Gustave Eiffel realized it.
To start with, the hall was completely restored. A new self-cleaning glass roof was fitted. The whole substance of the building was put back into the original state.
In fact the project consists of an insertion of a wooden unit in solid oak 1,7 m high, 22 m long and 14 m wide. The entire programme is embodied therein. Each individual workplace is incised into the wooden upper surface and covered by a “telephone’-dome in Plexiglas. The four lateral surfaces contain archives, cloakrooms and the kitchen. Completely embedded in the body are the meeting room, the recreational room and the restrooms. The remaining space is taken up by technical transmission systems (computer, electricity, air condition, heating and water) and also by 18,3 m3 of soil, the bed for eight Ficus Panda trees.
Neither entrance hall nor reception were implemented, since visitors are guided by a peripheral path-system leading to all pertinent rooms. The individual offices are situated on both galleries.”
Submitted by: samaelm
Posted at: 2011-10-14 17:49:12
See full post and comment: http://9gag.com/gag/358751
Posts
RT @newsycombinator: Karmurl - Give Feedback on Websites to Get Feedback http://j.mp/pW9ktZ
codando ao som do mestre - http://t.co/dQdjkwzY
RT @epetrie: @josevalim @tenderlove at #gogaruco party http://t.co/LCurX9vA
RT @guimenga: http://t.co/lowTI7h5 Isso vc não vê no UFC!
RT @guimenga: http://t.co/lowTI7h5 Isso vc não vê no UFC!
RT @sa_vini: O Curso de Rails 3.1 Grátis do @fbazzarella repercutiu bem no blog: http://t.co/bR1wkqmy
RT @sa_vini: O Curso de Rails 3.1 Grátis do @fbazzarella repercutiu bem no blog: http://t.co/bR1wkqmy
skype virando um monstro RT @MacMagazine: Skype 5.4 para Mac Beta ganha integração com o Facebook - http://t.co/vug5wozD
Quanta bobagem - http://t.co/5Okb4VGP
vou ter que voltar a usar a versão ultra-slow do bundler :( - http://t.co/yH43eRKh
My Artists by @topdrawerapps is a must-have app for music lovers http://t.co/LVQCSoWx
RT @newsycombinator: TinyProj connects developers, designers, etc. with paid, short-term projects. http://j.mp/q4QL0B
RT @felipernb: Blog post de hoje: Trabalhando com TI na Europa http://t.co/hzmWSTvS