tag:blogger.com,1999:blog-77751481586629083872024-03-12T23:15:10.871-03:00tanob's thoughtsNerdices, idéias e coisas que posso achar "tri legal"Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.comBlogger16125tag:blogger.com,1999:blog-7775148158662908387.post-8827672282989304552008-12-09T11:30:00.004-02:002008-12-09T11:47:24.035-02:00Bookmarklet para Google ReaderPor algumas razões estou utilizando no dia-a-dia o Google Chrome (sim, ele não tem add-ons e é *extremamente* minimalista). Para contornar a falta de uma maneira de adicionar o feed da página atual no leitor de feeds, fiz o seguinte bookmarklet, que pode ser utilizado em qualquer outro browser:<div><br /></div><div><blockquote><br />javascript:(function(){function fs(){var r=[];for(var i=0,ls=document.getElementsByTagName('link');i<ls.length;i++)if(ls[i].type in {'application/rss+xml':0,'application/atom+xml':0})r.push(ls[i]);return r}var ls=fs();if(ls.length>0)location.href='http://fusion.google.com/add?feedurl='+encodeURIComponent(ls[0].href);else alert('No feeds available!');})()<br /></blockquote></div><div><br /><div><div><div>Como o engine do Blogger não me deixou criar um link com esse código, vais ter que copiar e criar na mão o bookmarklet na barra de favoritos.<div><br /></div><div>Ah, se não sabe, Control+B mostra a barra de favoritos no Chrome.</div><div><br /></div></div></div></div></div>Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com1tag:blogger.com,1999:blog-7775148158662908387.post-85297508807106307492008-10-01T17:50:00.004-03:002008-10-01T18:18:09.649-03:00LINQ e SQLEstava lendo uma das entrevistas da Computer World da série "The A-Z of Programming Languages", sobre <a href="http://www.computerworld.com.au/index.php/id;1149786074;pp;2">a linguagem C#</a>, e a parte abaixo me chamou a atenção:<br /><blockquote>"[I also learnt to] design the language to be well-toolable. [...] When you write your SELECT clause, you can’t tell what people are selecting from, or what they might select until after writing the FROM clause. There are things like that to keep in mind."[Anders Hejlsberg]</blockquote>No mesmo momento liguei a síntaxe SQL:<br /><br />SELECT nome FROM pessoas WHERE [clausula];<br /><br />com a empregada no <a href="http://en.wikipedia.org/wiki/LINQ">LINQ</a>:<br /><br />from nome in pessoas<br />where [clausula]<br />select nome;<br /><br />Reparem que a seleção dos campos e as clausulas ficam após a especificação de onde eles vêm, logo a IDE se benefícia disso para fornecer dicas e auto-completação, algo que em ambientes para SQL só acontece se os campos no SELECT forem prefixados com o nome da tabela...<br /><br />Isso demonstra o quão importante é o desenvolvimento da síntaxe da linguagem já pensando no que as ferramentas poderão auxiliar os desenvolvedores.<br /><br />PS.: ando desaparecido por causa do <a href="http://minerva.ufpel.edu.br/%7Emacarthy/nopcc/Proposta_Adriano.pdf">meu trabalho de conclusão de curso</a>, então entre trabalho e TCC não me sobra muito mais tempo além de ler alguns textos :)<br /><br /><blockquote></blockquote>Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-38474078990088254902007-08-28T00:11:00.000-03:002007-08-28T00:23:48.049-03:00Programação dinâmica & ConcorrênciaComo havia falado no post anterior, eis aqui a implementação de um processo servidor de resultados para cálculo de Fibonacci, juntamente com um "cache" dos resultados prévios.<br /><br /><pre><span style="font-weight: bold; color: rgb(0, 0, 0);">-module</span><span style="color: rgb(0, 0, 128);">(</span><span style="color: rgb(255, 0, 255);">fibserver</span><span style="color: rgb(0, 0, 128);">).</span><br /><span style="font-weight: bold; color: rgb(0, 0, 0);">-export</span><span style="color: rgb(0, 0, 128);">([</span><span style="color: rgb(255, 0, 255);">fibserver</span><span style="font-weight: bold; color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 255);">0</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">fibserver</span><span style="font-weight: bold; color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 255);">1</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">fib</span><span style="font-weight: bold; color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 255);">1</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">start</span><span style="font-weight: bold; color: rgb(0, 0, 0);">/</span><span style="color: rgb(0, 0, 255);">0</span><span style="color: rgb(0, 0, 128);">]).</span><br /><br /><span style="color: rgb(0, 0, 128);">fibserver()</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% Start the Fibonacci Server with some basic pre-defined values...</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">fibserver([{</span><span style="color: rgb(0, 0, 255);">0</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 255);">0</span><span style="color: rgb(0, 0, 128);">},</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">{</span><span style="color: rgb(0, 0, 255);">1</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 255);">1</span><span style="color: rgb(0, 0, 128);">}]).</span><br /><br /><span style="color: rgb(0, 0, 128);">fibserver(</span><span style="color: rgb(128, 0, 0);">Values</span><span style="color: rgb(0, 0, 128);">)</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">receive</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">{</span><span style="color: rgb(255, 0, 255);">getValue</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">ReqPid</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">X</span><span style="color: rgb(0, 0, 128);">}</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">ValueExists</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">lists:keymember(</span><span style="color: rgb(128, 0, 0);">X</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">1</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">Values</span><span style="color: rgb(0, 0, 128);">),</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">if</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">ValueExists</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">{</span><span style="color: rgb(255, 0, 255);">value</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">{</span><span style="color: rgb(0, 0, 0);">_</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">V</span><span style="color: rgb(0, 0, 128);">}}</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">lists:keysearch(</span><span style="color: rgb(128, 0, 0);">X</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">1</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">Values</span><span style="color: rgb(0, 0, 128);">);</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">true</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">V</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">notFound</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">end</span><span style="color: rgb(0, 0, 128);">,</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% Send to the request process the atom notFound, or the Fibonacci of X.</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">ReqPid</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">V</span><span style="color: rgb(0, 0, 128);">,</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">fibserver(</span><span style="color: rgb(128, 0, 0);">Values</span><span style="color: rgb(0, 0, 128);">);</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">{</span><span style="color: rgb(255, 0, 255);">putValue</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">ValueTuple</span><span style="color: rgb(0, 0, 128);">}</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">fibserver(</span><span style="color: rgb(128, 0, 0);">Values</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">++</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">[</span><span style="color: rgb(128, 0, 0);">ValueTuple</span><span style="color: rgb(0, 0, 128);">])</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">end</span><span style="color: rgb(0, 0, 128);">.</span><br /><br /><span style="color: rgb(0, 0, 128);">fib(</span><span style="color: rgb(128, 0, 0);">N</span><span style="color: rgb(0, 0, 128);">)</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% Ask the server for the Fibonacci of N...</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">fibServer</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">{</span><span style="color: rgb(255, 0, 255);">getValue</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">self(),</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">N</span><span style="color: rgb(0, 0, 128);">},</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">receive</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% If the value doesn't exist yet, then...</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">notFound</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% ...calculate it...</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">FibN</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">=</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">fib(</span><span style="color: rgb(128, 0, 0);">N</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">1</span><span style="color: rgb(0, 0, 128);">)</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">+</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">fib(</span><span style="color: rgb(128, 0, 0);">N</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 255);">2</span><span style="color: rgb(0, 0, 128);">),</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% ...update the server with this new value...</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">fibServer</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">!</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">{</span><span style="color: rgb(255, 0, 255);">putValue</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">{</span><span style="color: rgb(128, 0, 0);">N</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">FibN</span><span style="color: rgb(0, 0, 128);">}},</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% ...return the calculated value.</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">FibN</span><span style="color: rgb(0, 0, 128);">;</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">X</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% The value was already in the server.</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(128, 0, 0);">X</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">end</span><span style="color: rgb(0, 0, 128);">.</span><br /><br /><span style="color: rgb(0, 0, 128);">start()</span><span style="color: rgb(0, 0, 0);"> </span><span style="font-weight: bold; color: rgb(0, 0, 0);">-></span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% Just start the process identified by the atom 'fibServer',</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% as the execution of the fibserver:fibserver/0,</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% that means, module fibserver, function fibserver</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="font-style: italic; color: rgb(128, 128, 128);">% that receives zero parameters.</span><br /><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">register(</span><span style="color: rgb(255, 0, 255);">fibServer</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">spawn(</span><span style="color: rgb(255, 0, 255);">fibserver</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(255, 0, 255);">fibserver</span><span style="color: rgb(0, 0, 128);">,</span><span style="color: rgb(0, 0, 0);"> </span><span style="color: rgb(0, 0, 128);">[])).</span><br /><br /></pre>Coloquei alguns comentários, mas para o total entendimento do código, você deve ter uma <a href="http://erlang.org/doc/getting_started/part_frame.html">noção básica</a> sobre Erlang, qualquer dúvida só postar.<br /><br />Para testar:<br />$ erl<br />Erlang (BEAM) emulator version 5.5.2 [source] [async-threads:0] [kernel-poll:false]<br /><br />Eshell V5.5.2 (abort with ^G)<br />1> c(fibserver).<br />{ok,fibserver}<br />2> fibserver:start().<br />true<br />3> fibserver:fib(1000).<br />43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875<br /><br />O resultado é praticamente instantâneo :)<br /><br />PS.: me esqueci de comentar como sair do shell do Erlang, basta pressionar Control-C, e então "a[enter]", ou então executar a função halt().Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com1tag:blogger.com,1999:blog-7775148158662908387.post-75832407772546252762007-08-22T01:30:00.000-03:002007-08-22T02:30:36.384-03:00Brincando com ErlangUltimamente tenho visto <a href="http://del.icio.us/tanob/erlang">muitos posts</a> comentando sobre a linguagem Erlang, que é uma linguagem funcional para programação concorrente, embora alguns defendam que também é orientada à objeto, já que Erlang oferece envio de mensagens como método para sincronização e comunicação entre processos, e orientação à objeto, na teoria, nada mais é do que troca de mensagens entre os objetos.<br /><br />Como tive uma cadeira na faculdade sobre programação funcional (recomendo a todos aprenderem uma linguagem funcional ou de paradigma diferente do imperativo) usando Haskell, e gostei muito, resolvi começar a brincar com Erlang, que já tem um <a href="http://erlyweb.org/">framework web</a> e um <a href="http://www.erlang.org/doc/apps/mnesia/index.html">banco de dados</a> super escalável!<br /><br />Para começar, instalei o pacote "erlang" no Debian Etch, muito simples.<br /><br />Então vamos para nosso primeiro programa, "hello world" ou Fibonacci? Ok, ok...<br /><ol><li>Crie um arquivo chamado hello.erl, com o seguinte código:<br />-module(hello).<br />-export([hello/0]).<br /><br />hello() -> io:format("Hello world!~n").</li><li>Chame o interpretador Erlang com o comando "erl";</li><li>Compile o programa:<br />c(hello).</li><li>Isto deve gerar um aviso {ok, hello};</li><li>Vamos executar:<br />hello:hello().</li><li>Pronto, satisfeito?</li></ol><br />Agora vamos ver como implementar o cálculo de Fibonacci de um número em Erlang, repare que o nome do arquivo deve ser fibonacci.erl, combinando com o nome do módulo:<br />-module(fibonacci).<br />-export([fib/1]).<br /><br />fib(0) -> 0;<br />fib(1) -> 1;<br />fib(N) -> fib(N - 1) + fib(N - 2).<br /><br />Reparem que há um pattern matching nos 2 casos básicos, e após a implementação recursiva para qualquer N > 1, com base disso podemos diminuir um pouco o código:<br /><br />fib(N) when N =< 1 -> N;<br />fib(N) -> fib(N - 1) + fib(N - 2).<br /><br />A chamada desde código após a compilação é trivial, por exemplo:<br />fibonacci:fib(10)<br /><br />O código em Haskell é muito semelhante (como não seria com esse pingo de código? :D)<br /><br />fib n<br />| n <= 1 = n<br />| otherwise = fib (n-1) + fib (n-2)<br /><br />Vá brincando, tente números mais altos, com 50 já vai demorar bastante o resultado, o que me sugestiona implementar algum mecanismo de programação dinâmica, uma idéia para um próximo post é implementar isso usando um processo servidor de resultados, exercitando então o mecanismo de troca de mensagens.<br /><br />Finalizo por aqui, e <a href="http://home.hiwaay.net/%7Ejalison/Fib500.html">clique aqui</a> se quiser conferir a lista dos 500 primeiros valores para a série de Fibonacci.Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-28892414490951018252007-05-01T02:24:00.000-03:002007-05-01T02:27:35.054-03:00Que linguagem você é?<a href="http://www.bbspot.com/News/2006/08/language_quiz.php"><img src="http://www.bbspot.com/Images/News_Features/2006/08/language/php.jpg" alt="You are PHP. You enjoy the World Wide Web. You are constantly changing the way you do things, and this tends to confuse people who work with you." border="0" height="90" width="300" /><br />Which Programming Language are You?</a><br /><br /><br />Pô!!! PHP?!?! Sacanagem... :)<br /><br /><span style="font-style: italic;">Vi isto no <a href="http://devlog.waltercruz.com/que_linguagem_voce_e">blog do Walter Cruz</a>.</span>Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-15904673573102908812007-04-24T01:09:00.000-03:002007-04-24T01:36:17.442-03:00Olá via FeedBurnerAdeus aos feeds não rastreáveis do blogger :D<br /><br />Sempre ouvi (na realidade li) que o Feedburner oferece um excelente serviço, então decidi conferir, principalmente porque quero conferir quantas pessoas estão lendo meu blog.<br /><br />Leio muitos feeds, muito raramente vou ao site ler algo, então acompanhar quantas pessoas estão lendo teus textos pelos page views não dá, uma solução de <span style="font-style: italic;">tracking</span> dos feeds é necessária, e como pode ver (se estiver lendo através da página ;)) na direita está o "Feedburner FeedCount", que te informa o número de leitores do feed provido por este blog.<br /><br />Outro serviço legal do FeedBurner é o PingShot, que notifica vários servidores quando um novo post é publicado, muito útil, por exemplo, para usuários do Blogger como eu, que não possuem um serviço como este disponível.<br /><br />Para seguir a filosofia <acronym title="Don't Repeat Yourself">DRY</acronym>, editei o template do blog para não disponibilizar o feed que o Blogger provê. Para fazer isto vi que existe uma tag <b:include data="'blog'" name="'all-head-content'"/> entre o <head> e o <title>, esta tag é depois substituida por tags <link> e <meta>. Apenas substitui esta tag pelo código gerado por ela, substituídos os <link> relacionados a feed RSS/Atom dos posts pelo <link> oferencendo feed Atom do FeedBurner.Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com1tag:blogger.com,1999:blog-7775148158662908387.post-66450413499192117832007-04-15T22:41:00.000-03:002007-04-15T23:19:20.926-03:00Concordo: IE6 deve morrer<span style="font-style: italic;">Como o Blogger não suporta Trackback ainda, então vai na mão mesmo:<br /><a href="http://www.tableless.com.br/ie6-deve-morrer">http://www.tableless.com.br/ie6-deve-morrer</a><br /></span><br />Na última sexta-feira, <a href="http://en.wikipedia.org/wiki/Friday_13">13</a> por coincidência, tive 2 dores de cabeça com o IE6.<br /><br /><span style="font-weight: bold;">Problema #1</span>: um Javascript responsável por salvar alguns dados no servidor:<br /><br /><code><br />for (country in countries) { ... }<br /></code><br /><br />isso funciona no Firefox, porém o IE acusava um problema. Graças a um debugger de Javascript que tenho instalado, consegui constatar que era esta expressão a culpada, então um amigo falou: "Coloca um <span style="font-style: italic;">var</span> ali na declaração de <span style="font-style: italic;">country</span>". Dito e feito, o correto é:<br /><br /><code><br />for (var country in countries) { ... }<br /></code><br /><br /><span style="font-weight: bold;">Problema #2:</span> tags A com background-image, quando se passava o mouse por cima do link, algumas vezes, acontecia que a imagem desaparecia e aparecia novamente, em inglês <span style="font-style: italic;">flickering</span>. Pesquisando vi que isso já é um bug conhecido do IE6, <a href="http://www.fivesevensix.com/studies/ie6flicker/">uma página</a> fazia uma série de teorias explicando o porque daquele bug, <a href="http://plone.org/documentation/how-to/flickering-background-images-internet-explorer">outra</a> apenas relatava a solução que foi adotada, a <a href="http://www.brunildo.org/test/IEAbackima.html">terceira e última</a> foi mais útil, explica que a causa do problema está nos <span style="font-style: italic;">response headers</span> HTTP, mais precisamente no <span style="font-style: italic;">Expires</span>. Como queria uma solução mais rápida e que respondesse na mesma moeda ao IE, optei pela solução que usa um Javascript apenas no IE6, que altera um parâmetro não documentado do browser:<br /><br /><span style="font-style: italic; color: rgb(128, 128, 128);"><!--[if IE 6]><script type="text/javascript"></span><br /><span style="font-style: italic; color: rgb(128, 128, 128);">try {</span><br /><span style="font-style: italic; color: rgb(128, 128, 128);"> document.execCommand("BackgroundImageCache", false, true);</span><br /><span style="font-style: italic; color: rgb(128, 128, 128);">} catch(err) {}</span><br /><span style="font-style: italic; color: rgb(128, 128, 128);"></script><![endif]--></span><br /><br />Solucionado! Muito melhor que perder tempo² (meu tempo desenvolvendo uma solução para retornar as imagens com o header <span style="font-style: italic;">Expires</span>, e o tempo do processador do servidor depois para servir as imagens através dessa solução e não do procedimento padrão do servidor HTTP).Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com1tag:blogger.com,1999:blog-7775148158662908387.post-67860262734838093392007-04-13T20:17:00.000-03:002007-04-13T20:21:10.493-03:00My nerd scoreComo vi outros nerds mostrando seus scores, então aqui está:<br /><br /><a href="http://www.nerdtests.com/ft_nq.php?im"><img src="http://www.nerdtests.com/images/ft/nq.php?val=5771" alt="I am nerdier than 90% of all people. Are you nerdier? Click here to find out!" /></a><br /><br />Tinha feito este teste há algum tempo atrás e lembro que meu score foi 84, que evolução! :DAdriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-58681027335556569822007-04-08T04:04:00.000-03:002007-04-08T04:12:10.444-03:00Lições relacionadas a JavascriptTrabalhando com Javascript e "Ajax" em um projeto tomei as seguintes lições:<br /><ul><li>Opera 8.5 não lida bem com respostas cujo mime-type é 'application/json', a solução foi atualizar para a 9.0;<br /></li><li>IE não gosta de vírgulas extra em suas matrizes, por exemplo [1,2,3,], ele interpreta aquela última vírgula como um outro elemento da matriz;<br /></li><li>Usando as facilidades "Ajax" do jQuery, caso ocorra uma exceção dentro da callback de success, o jQuery irá chamar a callback de error;</li></ul>Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-69932895341299365322007-03-24T12:02:00.000-03:002007-03-24T12:50:59.397-03:00JQuery, CSS e ids (X)HTMLEm um projeto que estou trabalhando no momento estou usando o <a href="http://jquery.org/" target="_blank">JQuery</a>, porém me deparei com um problema ao tentar utilizar o seu $() com elementos que contenham ids com caracteres como ponto e dois-pontos, que são <a href="http://www.w3.org/TR/html401/types.html#type-id" target="_blank">caracteres válidos em ids</a>.<br /><br />Preparei um arquivo de testes e postei o problema na lista do JQuery, e em alguns minutos obtive entre as respostas uma que apontava que já existia um <a href="http://dev.jquery.com/ticket/143" target="_blank">bug report para este problema</a> (aqui entra a lição de sempre procurar pelo problema no bug tracker do projeto!), que até agora ainda não foi solucionado, existe uma sugestão de patch que altera a expressão regular do CSS selector do JQuery para uma solução parecida com o que já existe na especificação do CSS...<br /><br /><pre><br /><span style="font-weight: bold;color: #000000;"><style></span><br /><span style="font-weight: bold;color: #800080;">#test</span><span style="color: #000000;"></span><span style="color: #800080;">.x</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">{</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">background-color:</span><span style="color: #000000;"> </span><span style="color: #800000;">green</span><span style="font-weight: bold;color: #000000;">;</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">color:</span><span style="color: #000000;"> </span><span style="color: #800000;">yellow</span><span style="font-weight: bold;color: #000000;">;</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">}</span><br /><span style="font-weight: bold;color: #000000;"></style></span><br /><span style="color: #000000;">...</span><br /><span style="font-weight: bold;color: #000000;"><p</span><span style="color: #008000;"> id=</span><span style="color: #aa0000;">"test.x"</span><span style="font-weight: bold;color: #000000;">></span><span style="color: #000000;">P with id 'test.x'.</span><span style="font-weight: bold;color: #000000;"></p></span><br /></pre><br /><br />O código acima não irá funcionar como esperado, ele na verdade seleciona o elemento com id 'test' e classe 'x', para ter o efeito desejado deve-se usar '#test\.x', ou seja, "escapa"-se o ponto, o que informa ao interpretador CSS para cancelar a busca pela classe.<br /><br />A solução temporária é eu aplicar o patch e compilar a minha própria versão do JQuery...Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-76191665433194272082007-03-19T01:56:00.000-03:002007-03-19T02:04:11.971-03:00Ano novo copyright velho?Parece que o ano de 2006 ainda não acabou, pelo menos para a página de login do Gmail, porque na parte interna já se está com o copyright atualizado para 2007...<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_GXBR7ak83lI/Rf4ZDAjnyvI/AAAAAAAAADg/lBDus0nJsnY/s1600-h/gmail_externa.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp3.blogger.com/_GXBR7ak83lI/Rf4ZDAjnyvI/AAAAAAAAADg/lBDus0nJsnY/s320/gmail_externa.png" alt="" id="BLOGGER_PHOTO_ID_5043496172181244658" border="0" /></a>... enquanto na interna:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_GXBR7ak83lI/Rf4ZZQjnyxI/AAAAAAAAADw/VORi4DH7LKM/s1600-h/gmail_interna.png"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp0.blogger.com/_GXBR7ak83lI/Rf4ZZQjnyxI/AAAAAAAAADw/VORi4DH7LKM/s320/gmail_interna.png" alt="" id="BLOGGER_PHOTO_ID_5043496554433334034" border="0" /></a>PS.: a qualidade desse htmlarea do blogger é péssima²³Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-22025158582121816172007-03-18T23:35:00.000-03:002007-03-18T23:53:23.341-03:00OpenSearchFinalmente tive um tempo para olhar a especificação do <a href="http://www.opensearch.org/" target="_blank">OpenSearch</a> e aproveitei para implementar uma descrição para o <a href="http://www.mininova.org/" target="_blank">Mininova.org</a>, um que procura normalmente, e outro que já procura e retorna o resultado ordenado pelo número de seeds, o que facilita muito a vida ;)<br /><br />A implementação está <a href="http://minerva.ufpel.edu.br/%7Eadrianob_ifm/opensearch/">aqui</a>.Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-69369372926099017452007-01-21T17:16:00.000-02:002007-01-21T17:49:14.394-02:00An Inconvenient TruthÓtimo filme que mostra os efeitos e causas do aquecimento global, ao final dá conselhos de atitudes que devem ser tomadas como por exemplo: privilegiar transportes coletivos, fazer a separação do lixo e procurar carros e eletrônicos mais "ecologicamente limpos".<br /><br />No final o Al Gore poderia ter deixado pra lá todo aquele papo que o povo estadunidense já fez outras revoluções e que poderia lidar muito bem com este problema, mas felizmente essa conversa é curta.<br /><br />Gore salienta algo importante, que podemos solucionar o problema ecológico sem prejudicar a indústria, até mesmo permitiria a criação de mais postos de trabalho.<br /><br />Frase do filme: "É difícil fazer um homem entender algo se seu salário depender de seu não entendimento." ("<span style="font-style: italic;">It is difficult to get a man to understand something when his salary depends upon his not understanding it.</span>")<br /><br />Outro filme que vi este final de semana e que gostei muito é <span style="font-style: italic;">Lord of War</span> (pt-br: O Senhor das Armas, pt-pt: O Senhor da Guerra), que mostra como funciona o comércio de armas nas guerras, sendo Nicholas Cage o contrabandista de armas.<br /><br />Frase do filme: "OS MAIORES FORNECEDORES DE ARMAS NO MUNDO SÃO USA, INGLATERRA, RÚSSIA, FRANÇA E CHINA. ELES SÃO TAMBÉM OS CINCO MEMBROS PERMANENTES DO CONSELHO DE SEGURANÇA DAS NAÇÕES UNIDAS."<br /><br /><a href="http://omedi.blogspot.com/2007/01/cinema-o-filme-mais-assustador-de.html" target="_blank">Dica do "<span style="font-style: italic;">An Inconvenient Truth</span>" veio do OMEdI.</a>Adriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-46052853151318119982006-12-29T20:47:00.000-02:002006-12-29T20:57:35.782-02:00Menos um na wishlist<div style="text-align: left;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.submarino.com.br/books_productdetails.asp?ProdTypeId=1&ProdId=238302" target="_blank"><img src="http://i.s8.com.br/images/books/cover/img2/238302.jpg" alt="" border="0" /></a><br /></div>Valeu Flávio!!! :DAdriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-37565894279827576422006-11-23T13:18:00.000-02:002006-11-24T00:47:16.313-02:00Easter eggs open-sourceNão lembro o motivo, mas outro dia estava falando com o pessoal do escritório sobre Easter Eggs, nesta conversa me falaram sobre um que tem no <a href="http://www.eeggs.com/items/48349.html">Notepad</a> entre alguns outros.<br /><br />Fiquei depois pensando se existem Easter Eggs em softwares que nasceram open-source, achei que pelo motivo do código ser acessível não haveria tanta emoção em se esconder alguma brincadeira dentro do software. Pois me enganei! Ontem por coincidência recebi um email do Notícias Linux que traz um <a href="http://www.noticiaslinux.com.br/nl1164246954.html">link</a> com alguns casos, dentre eles um que eu não me lembrava, o do "moo" no apt-get.<br />Me lembrei agora há pouco de um no <a href="http://www.eeggs.com/items/18686.html">PHP</a>, e claro, o do "import this" do Python (<a href="http://www.python.org/dev/peps/pep-0020/">The Zen of Python</a>).<br /><br />Aquele "Star Wars" que vem no OpenOffice 2 me rendeu alguns minutos de diversão, mesmo estando em alemão, e o Easter Egg do Notepad eu testei, mas como não tinha a fonte necessária para renderizar o texto, não teve tanta graça :DAdriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0tag:blogger.com,1999:blog-7775148158662908387.post-12260151481846397042006-10-28T15:16:00.000-03:002006-10-28T18:31:11.665-03:00Tá meio apertado aqui não?Comprei um HD de 160GB (uau, bom poderia ser maior...) há uns 2 meses para substituir meu velho HD de 40GB, e na hora da decisão pelo modo de particionar, e qual sistema de arquivos vou utilizar, optei em utilizar o <a href="http://en.wikipedia.org/wiki/Lvm">LVM</a>.<br /><br />Deixei a partição root com 10GB formatados como reiserfs, e criei uma outra partição primária com 80GB, marcada como LVM (type 0x8e). Criei volumes lógicos para música (15GB), vídeos (15GB), downloads em geral (15GB), e até mesmo pro meu /home (5GB).<br /><br />Formatei as partições como <a href="http://en.wikipedia.org/wiki/Xfs">XFS</a>, pois já estava pensando que no futuro, quando necessário, este sistema de arquivos me facilitaria a vida ao estender os volumes lógicos...<br /><br />E não é que ontem recebi um aviso do Azureus que o espaço já tinha acabado pros meus downloads? Corri para a linha de comando e evoquei os seguintes comandos mágicos:<br /><br /># lvextend -L+5G /dev/data_vg/misc_lv<br />File descriptor 11 left open<br />Extending logical volume misc_lv to 20,00 GB<br />Logical volume misc_lv successfully resized<br /><br /># xfs_growfs /var/misc<br />xfs_growfs: XFS_IOC_FSGROWFSDATA xfsctl failed: Não há espaço disponível no dispositivo<br /><br />Oh-oh! Falta de espaço?! Claro né, porque que estou dando um resize então?!<br />Tinha apenas 200KB de espaço livre, acredito que isso não era suficiente pro XFS efetuar o resize, então movi algumas coisas de lugar e...<br /><br /># xfs_growfs /var/misc<br />data blocks changed from 3932160 to 5242880<br /><br />Shazam! Na hora, sem desmontar, sem reiniciar o computador, sem parar nenhuma aplicação, aumentou minha partição para 20GB:<br /><br /># df -h | grep misc<br />/dev/mapper/data_vg-misc_lv 20G 15G 5,1G 75% /var/misc<br /><br />Muito bom, a única coisa que não gostei foi daquele problema de falta de espaço, me fez ter que mover arquivos, bem que o sistema de arquivos poderia já ter um espaço reservado para estes casos.<br /><br />Fica a dica, se estiver no Linux, use o LVM para gerenciar as partições, é uma solução muito flexível, além de não deixar o teu download parado por muito tempo pela falta de espaço :DAdriano Bonathttp://www.blogger.com/profile/16194070610286871533noreply@blogger.com0