<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>tanob&#39;s blog</title>
 <link href="https://blog.tanob.me/atom.xml" rel="self"/>
 <link href="https://blog.tanob.me/"/>
 <updated>2015-11-27T01:53:33+00:00</updated>
 <id>https://blog.tanob.me</id>
 <author>
   <name>Adriano Bonat</name>
   <email>adrianob@gmail.com</email>
 </author>

 
 <entry>
   <title>Resetting the audio system in OSX</title>
   <link href="https://blog.tanob.me/2015/11/26/resetting-the-audio-system-in-osx.html"/>
   <updated>2015-11-26T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2015/11/26/resetting-the-audio-system-in-osx</id>
   <content type="html">&lt;p&gt;How many times have you come through this scenario: you join an online meeting and say “Hello”, the person in the other side can see your mouth is moving and says “I can’t hear you”, you start looking at the different levels of sound preferences and it all looks right, still for some reason the mic input level doesn’t move.&lt;/p&gt;

&lt;p&gt;Next time try killing the “coreaudiod” process in OSX. After that just try closing and opening the video call app, or reloading the page if it’s inside a browser.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog.tanob.me/files/2015-11-26-resetting-the-audio-system-in-osx/activity-monitor-kill-coreaudiod.png&quot; alt=&quot;Killing coreaudiod via Activity Monitor&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The only downside of this is that the speaker menu icon at the system menu bar will get gray, though you can still adjust the sound output level through the Sound panel at System Preferences.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Podcast sobre Entrega Contínua para apps mobile</title>
   <link href="https://blog.tanob.me/2015/04/07/podcast-tecnologicamente-arretado.html"/>
   <updated>2015-04-07T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2015/04/07/podcast-tecnologicamente-arretado</id>
   <content type="html">&lt;p&gt;Dei uma entrevista junto com meu colega na ThoughtWorks, &lt;a href=&quot;https://twitter.com/obehdi&quot;&gt;Obedi Ferreira&lt;/a&gt;, para o podcast Tecnologicamente Arretado com o tema “Entrega Contínua para dispositivos móveis”. &lt;a href=&quot;http://tecnologicamentearretado.com.br/2015/03/31/entrega-continua-para-dispositivos-moveis-com-bonat-e-obedi/&quot;&gt;Clique aqui&lt;/a&gt; para conferir!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Debugging capybara-webkit</title>
   <link href="https://blog.tanob.me/2014/11/12/debugging-capybara-webkit.html"/>
   <updated>2014-11-12T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2014/11/12/debugging-capybara-webkit</id>
   <content type="html">&lt;p&gt;If you ever run into weird issues with &lt;a href=&quot;https://github.com/thoughtbot/capybara-webkit&quot;&gt;capybara-webkit&lt;/a&gt; you might find some clues about them by enabling logging:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-ruby&quot; data-lang=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Capybara&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:webkit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enable_logging&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After that it will print in stdout the commands that are being executed and their results, for example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;
Received &quot;Visit(https://secure.example.com)&quot;
Started &quot;Visit(https://secure.example.com)&quot;
Load started
&quot;Visit(https://secure.example.com)&quot; started page load
Started request to &quot;https://secure.example.com/&quot;
Finished &quot;Visit(https://secure.example.com)&quot; with response &quot;Success()&quot;
Received 0 from &quot;https://secure.example.com/&quot;
Page finished with false
Load finished
Page load from command finished
Wrote response false &quot;{&quot;class&quot;:&quot;InvalidResponseError&quot;,&quot;message&quot;:&quot;Unable to load URL: https://secure.example.com/ because of error loading https://secure.example.com/: Unknown error&quot;}&quot;
/Users/tanob/.rvm/gems/ruby-2.1.3/gems/capybara-webkit-1.3.1/lib/capybara/webkit/browser.rb:275:in `check&#39;: Unable to load URL: https://secure.example.com/ because of error loading https://secure.example.com/: Unknown error (Capybara::Webkit::InvalidResponseError)
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This helped me to find &lt;a href=&quot;https://github.com/thoughtbot/capybara-webkit/issues/674&quot;&gt;Github Issue #674&lt;/a&gt; in capybara-webkit about the weird “Received 0” message. Looks like it’s related to the upgrade to OSX Yosemite and the workaround for now is to ignore SSL errors (&lt;code&gt;session.driver.browser.ignore_ssl_errors&lt;/code&gt;).&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Be cautious when using checked exceptions</title>
   <link href="https://blog.tanob.me/2013/11/30/be-cautious-when-using-checked-exceptions.html"/>
   <updated>2013-11-30T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2013/11/30/be-cautious-when-using-checked-exceptions</id>
   <content type="html">&lt;p&gt;While I think checked exceptions are useful when you want to make it explicit in the API that calling a specific method in the interface can have an exception as result, it might be harmful if used indiscriminately.&lt;/p&gt;

&lt;p&gt;The issues are related to the fact that the throws declaration is part of the method signature.&lt;/p&gt;

&lt;p&gt;Consequences:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;it will restrict the usage of some frameworks. Example: in a more functional style with Guava you won’t be able to use a &lt;a href=&quot;http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Function.html&quot;&gt;Function&lt;/a&gt; to transform lists if any call in the implementation has a checked exception. In this particular case it will make you handle the exception in each transformation.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-java&quot; data-lang=&quot;java&quot;&gt;&lt;span class=&quot;n&quot;&gt;Lists&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Function&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;From&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;To&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nd&quot;&gt;@Override&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;To&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;From&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;transformIt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// what if it has a checked-exception?&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;});&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;it violates the &lt;a href=&quot;http://en.wikipedia.org/wiki/Open/closed_principle&quot;&gt;Open/Closed Principle&lt;/a&gt;, as Uncle Bob mentions in the book Clean Code. A change in the signature of a method will have a cascade effect in the call hierarchy of that method.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wrote this post after refactoring some code that was using checked exceptions. The funny part was that there was no place in the codebase actually throwing the exception.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Replacing colors with ImageMagick</title>
   <link href="https://blog.tanob.me/2013/08/16/replacing-colors-with-imagemagick.html"/>
   <updated>2013-08-16T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2013/08/16/replacing-colors-with-imagemagick</id>
   <content type="html">&lt;p&gt;I’ve run out of black ink on my printer and I had to print one page full of black stuff,
the color of the document itself wasn’t important, the content just had to be readable.&lt;/p&gt;

&lt;p&gt;I’ve tried to use OSX built-in Quartz filters to change all black pixels to blue, and
there’s actually one already called “Blue Tone” but it didn’t work that well for the
document (PDF) that I had to print. It couldn’t change the black text and just changed
other images and drawings to blue. I’ve even tried to mess up with &lt;a href=&quot;http://en.wikipedia.org/wiki/ColorSync&quot;&gt;ColorSync&lt;/a&gt;, which is
a built-in tool in OSX that allows you to create your own filters.&lt;/p&gt;

&lt;p&gt;Tired of that and thinking that it had to be simpler than that, I’ve remembered of the
command-line tool called &lt;code&gt;convert&lt;/code&gt;, which is provided by ImageMagick. I just had to do
one Google search to find &lt;a href=&quot;http://www.imagemagick.org/Usage/color_basics/#replace&quot;&gt;how to do it&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ convert blackish_doc.png -fill blue -opaque black blueish_doc.png
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Just had to convert the PDF to PNG before using this line and it saved my life ;)&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Android maven project with a native dependency</title>
   <link href="https://blog.tanob.me/2013/07/02/android-maven-project-with-a-native-dependency.html"/>
   <updated>2013-07-02T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2013/07/02/android-maven-project-with-a-native-dependency</id>
   <content type="html">&lt;p&gt;In my current Android project we’re using the &lt;a href=&quot;https://code.google.com/p/maven-android-plugin&quot;&gt;Android maven plugin&lt;/a&gt; and recently we got
a pre-built native library (.so) as a dependency.&lt;/p&gt;

&lt;p&gt;I had some trial and errors and had to read the plugin’s source code to get it working,
the project’s wiki &lt;a href=&quot;https://code.google.com/p/maven-android-plugin/wiki/NativeLibsAsDependencies&quot;&gt;about it&lt;/a&gt; isn’t up-to-date on how to do it.&lt;/p&gt;

&lt;p&gt;First, as this native dependency is not in a Maven repository, we’re using the &lt;a href=&quot;http://maven.apache.org/plugins/maven-install-plugin/&quot;&gt;maven install plugin&lt;/a&gt;
to install it in the local maven repository:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-install-plugin&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.4&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;inherited&amp;gt;&lt;/span&gt;false&lt;span class=&quot;nt&quot;&gt;&amp;lt;/inherited&amp;gt;&lt;/span&gt;

        &lt;span class=&quot;nt&quot;&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;id&amp;gt;&lt;/span&gt;foo-native&lt;span class=&quot;nt&quot;&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;goals&amp;gt;&amp;lt;goal&amp;gt;&lt;/span&gt;install-file&lt;span class=&quot;nt&quot;&gt;&amp;lt;/goal&amp;gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;initialize&lt;span class=&quot;nt&quot;&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;nt&quot;&gt;&amp;lt;file&amp;gt;&lt;/span&gt;${project.basedir}/tmp/libFoo.so&lt;span class=&quot;nt&quot;&gt;&amp;lt;/file&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.foo.bar&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;libFoo&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;nt&quot;&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;so&lt;span class=&quot;nt&quot;&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;nt&quot;&gt;&amp;lt;classifier&amp;gt;&lt;/span&gt;armeabi&lt;span class=&quot;nt&quot;&gt;&amp;lt;/classifier&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It is important to set the &lt;code&gt;packaging&lt;/code&gt; as “so” and set the &lt;code&gt;classifier&lt;/code&gt; with the shared-object’s
target architecture. In our case it is “armeabi” but the plugin also recognize these others:
“armeabi-v7a”, “mips” and “x86”.&lt;/p&gt;

&lt;p&gt;After getting the dependency installed you’ll list it under your &lt;code&gt;&amp;lt;dependencies&amp;gt;&lt;/code&gt; like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-xml&quot; data-lang=&quot;xml&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.foo.bar&lt;span class=&quot;nt&quot;&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;libFoo&lt;span class=&quot;nt&quot;&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0&lt;span class=&quot;nt&quot;&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;type&amp;gt;&lt;/span&gt;so&lt;span class=&quot;nt&quot;&gt;&amp;lt;/type&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;classifier&amp;gt;&lt;/span&gt;armeabi&lt;span class=&quot;nt&quot;&gt;&amp;lt;/classifier&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That’s it, after running &lt;code&gt;mvn clean package&lt;/code&gt; the generated APK should have the &lt;code&gt;.so&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ jar tf app/target/app.apk | grep armeabi
lib/armeabi/libFoo.so
&lt;/code&gt;&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>Custom vimrc for project specific settings</title>
   <link href="https://blog.tanob.me/2013/04/29/custom-vimrc-for-project-specific-settings.html"/>
   <updated>2013-04-29T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2013/04/29/custom-vimrc-for-project-specific-settings</id>
   <content type="html">&lt;p&gt;Today I wanted to load some custom settings in my vim session when working on a particular project. I wanted that to avoid polluting my user’s vimrc with project specific things. After some googling around I found (not surprisingly!) a StackOverflow &lt;a href=&quot;http://stackoverflow.com/questions/456792/vim-apply-settings-on-files-in-directory&quot;&gt;thread&lt;/a&gt;. The usage of a plugin to scan directories just sounded too much, not even mentioning the load time increase that would add. I just wanted something simple like an environment variable.&lt;/p&gt;

&lt;p&gt;As I couldn’t use what the thread mentions (MYVIMRC and VIMINIT), I just went ahead and added the following to my vimrc:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-vim&quot; data-lang=&quot;vim&quot;&gt;&lt;span class=&quot;c&quot;&gt;&amp;quot; This allows project specific vim settings&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; filereadable&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;$CUSTOM_VIMRC&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  source $CUSTOM_VIMRC
&lt;span class=&quot;k&quot;&gt;endif&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With that I just export &lt;code&gt;CUSTOM_VIMRC&lt;/code&gt; when loading my project environment settings (you can use fancy things like &lt;a href=&quot;http://www.virtualenv.org/&quot;&gt;virtualenv&lt;/a&gt; or a shell alias that does a bunch of nested calls). For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export CUSTOM_VIMRC=/Volumes/Project/.vimrc
&lt;/code&gt;&lt;/pre&gt;

</content>
 </entry>
 
 <entry>
   <title>Javascript object initialization</title>
   <link href="https://blog.tanob.me/2013/04/28/javascript-object-initialization.html"/>
   <updated>2013-04-28T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2013/04/28/javascript-object-initialization</id>
   <content type="html">&lt;p&gt;I was about to write this post since a long time ago, when I was talking with two of my friends at work.
I was reading some Javascript code that they were writing and I’ve noticed they were writing “classes” like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Hello, &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Ford Prefect&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Objects in Javascript are basically a map (aka hash) of keys to values. A key that maps to a function can be considered a method, and a key that maps to a primitive type is what we call a public attribute (aka instance variable). This implementation works exactly like that, when we call &lt;code&gt;User&lt;/code&gt; it will return a map with a key (&lt;code&gt;greeting&lt;/code&gt;) that points to a function. In this case &lt;code&gt;name&lt;/code&gt; isn’t an attribute and &lt;code&gt;greeting&lt;/code&gt; can access its value because in Javascript the inner functions get access to all outer variables and arguments, that’s what’s called a &lt;em&gt;closure&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;While I understand that this is valid Javascript and it works, I knew you can also write it like this:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;greeting&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Hello, &amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Ford Prefect&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The ones that are more seasoned to traditional object oriented languages (e.g. Java, Python, Ruby) will recognize that the first function works like an object constructor, it receives a &lt;code&gt;name&lt;/code&gt; parameter and stores it in an instance variable. This “class” also has a “method” in its prototype that uses that instance variable to build the user’s greeting.&lt;/p&gt;

&lt;p&gt;This implementation has some differences in comparison with the first one:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;name is a public attribute, it can be read and changed by any code external to that object;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;greeting&lt;/code&gt; is added to the &lt;code&gt;User&lt;/code&gt;’s prototype;&lt;/li&gt;
  &lt;li&gt;we’re using &lt;code&gt;new&lt;/code&gt; to initialize the object before calling &lt;code&gt;greeting&lt;/code&gt;;&lt;/li&gt;
  &lt;li&gt;any method that we add to &lt;code&gt;User&lt;/code&gt;’s prototype will be available to any existing or future instance of &lt;code&gt;User&lt;/code&gt;;&lt;/li&gt;
  &lt;li&gt;the object initialization &lt;a href=&quot;http://stackoverflow.com/questions/3493252/javascript-prototype-operator-performance-saves-memory-but-is-it-faster&quot;&gt;is&lt;/a&gt; &lt;a href=&quot;http://ejohn.org/blog/simple-class-instantiation/&quot;&gt;faster&lt;/a&gt; and the object consumes less memory when you create lots of instances of that class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regarding the memory consumption bit I’ve decided to run a quick experiment to prove it. You can find the two implementations &lt;a href=&quot;https://github.com/tanob/tanob.github.com/tree/master/files/2013-04-28-javascript-object-initialization/&quot;&gt;here&lt;/a&gt; that you’ll run with the &lt;a href=&quot;http://nodejs.org/&quot;&gt;node.js&lt;/a&gt; runtime and below is a graph that compares the memory consumption outputs.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://blog.tanob.me/files/2013-04-28-javascript-object-initialization/graph.png&quot; alt=&quot;Javascript memory consumption using different object instantiation&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With that in mind I’d strongly suggest to use the patterns that Crockford shows in his text &lt;a href=&quot;http://www.crockford.com/javascript/private.html&quot;&gt;Private Members in JavaScript&lt;/a&gt;, following that you’ll get the benefits of prototype when dealing with public stuff and you can mix it with closures to make some values private in your implementation.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>CI Configuration Under Control</title>
   <link href="https://blog.tanob.me/2013/02/27/ci-configuration-under-control.html"/>
   <updated>2013-02-27T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2013/02/27/ci-configuration-under-control</id>
   <content type="html">&lt;p&gt;One of the practices of Continuous Integration (CI) is to keep everything you need to build your system in one place, even better if it is version controlled so, for example, you can see the diff that made something break or to help you understand when certain functionality got introduced.&lt;/p&gt;

&lt;p&gt;Usually together with that people use CI servers that are constantly looking for changes in your version control system (VCS). These servers are configured to know where to find the source code for your projects, they know how to build them, they know the sequence of builds required to leave your artifacts ready to be deployed. It’s highly recommended that they also know how to deploy your application to the different environments you may have (e.g. QA, UAT, Pre-Production, Production).&lt;/p&gt;

&lt;p&gt;The problem I’ve noticed in most of the projects using CI servers is that their configuration is not under version control together with your source code. This isn’t a &lt;a href=&quot;http://paulhammant.com/2011/09/30/branchable-continuous-integration/&quot;&gt;new idea&lt;/a&gt; and here are some benefits I can see on that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;having the configuration in a text file using some format like YAML, JSON or XML allows you to use your &lt;a href=&quot;http://www.vim.org&quot;&gt;preferred text editor&lt;/a&gt; and avoids the slow configuration through the UI;&lt;/li&gt;
  &lt;li&gt;version control will tell you who made a change, what part of the configuration got changed, when did it happen and the reason why it changed will be in the commit message;&lt;/li&gt;
  &lt;li&gt;you can easily revert the change;&lt;/li&gt;
  &lt;li&gt;it allows you to see your CI configuration evolving together with your system’s code;&lt;/li&gt;
  &lt;li&gt;if you’re migrating to another CI server that supports a text configuration file you can easily transform your current configuration, reducing the potential for &lt;a href=&quot;http://en.wikipedia.org/wiki/Vendor_lock-in&quot;&gt;“lock in”&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having the configuration as a text file shouldn’t make you go crazy on the number of commands per job, I highly recommend your job configuration to just call a few commands, e.g. bundle install &amp;amp;&amp;amp; rake test package. Remember that the developers should be using the same commands on their development machines to verify their changes before pushing them, so make it simple!&lt;/p&gt;

&lt;p&gt;In summary, I see two ways on how you can implement this idea:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;VCS totally embraced by the CI server, when you install it you’ll have to provide from where it should consume and save the configuration changes. With this approach the configuration can work both ways between UI and VCS;&lt;/li&gt;
  &lt;li&gt;VCS is not embraced. With this one you’ll have to workaround it, just disable the UI administration and create a job/pipeline that will watch the VCS and on every change it will reconfigure itself, e.g. jobs that are running but got removed from the config should be stopped and removed from the UI, new jobs will show up in the UI and will start being monitored by the CI server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’m not aware of any CI server that follows the first approach.&lt;/p&gt;

&lt;h2 id=&quot;implementing-it-with-thoughtworks-studios-gohttpwwwthoughtworks-studioscomgo-continuous-delivery&quot;&gt;Implementing it with &lt;a href=&quot;http://www.thoughtworks-studios.com/go-continuous-delivery&quot;&gt;ThoughtWorks Studios’ Go&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;You can see how I’ve implemented it with Go &lt;a href=&quot;https://github.com/tanob/go-config-under-control&quot;&gt;here&lt;/a&gt;. In the case of Go the configuration is XML-based and they provide a &lt;a href=&quot;https://github.com/tanob/go-config-under-control/blob/master/cruise-config.xsd&quot;&gt;XSD&lt;/a&gt; so we can actually validate if its syntax is fine.&lt;/p&gt;

&lt;p&gt;There’s a Ruby script that will merge the pipeline configurations into Go’s, its config file is usually located in /etc/go/cruise-config.xml. Go watches it looking for changes, when there’s any it tries to apply it and if everything is fine it will update its internal configuration file. By the way, internally they keep it versioned using Git!&lt;/p&gt;

&lt;p&gt;In case of some problem in the configuration, Go will simply reject it and will output the error in the server’s log. It will also warn you about it through its UI. Notice that the merge script starts watching the log file after applying the changes, if some error happens it will output it so the developer can easily fix it.&lt;/p&gt;

&lt;p&gt;Talking about problems, here are some I had while playing with this idea:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;we all know that XML isn’t that human friendly, it at least makes editing hard, maybe we could have the actual configuration in another format, like YAML;&lt;/li&gt;
  &lt;li&gt;it is fundamental to have a tool to validate your changes locally. In the case of my implementation I’ve wrote a Rake task that uses the XSD but that didn’t help me when I’ve configured a &lt;a href=&quot;https://github.com/tanob/go-config-under-control/commit/d4dab631ddb216583c0d5418711c18bbb36d6567&quot;&gt;Stage’s name with spaces&lt;/a&gt;, Go rejected that but the syntax was fine, maybe it can be improved with a tool like &lt;a href=&quot;https://github.com/travis-ci/travis-lint&quot;&gt;travis-lint&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;other-ci-servers&quot;&gt;Other CI Servers&lt;/h2&gt;

&lt;p&gt;I haven’t looked if it is possible to do that in other CI servers like &lt;a href=&quot;http://jenkins-ci.org/&quot;&gt;Jenkins&lt;/a&gt; or &lt;a href=&quot;http://www.atlassian.com/software/bamboo/overview&quot;&gt;Bamboo&lt;/a&gt;, so let me know of your experiences.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Transparent SSH tunnel using the ProxyCommand configuration</title>
   <link href="https://blog.tanob.me/2012/07/17/transparent-ssh-tunnel-using-the-proxycommand-configuration.html"/>
   <updated>2012-07-17T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2012/07/17/transparent-ssh-tunnel-using-the-proxycommand-configuration</id>
   <content type="html">&lt;p&gt;I’m currently working on a client that restricts the IPs allowed to SSH into their servers, of course, for security reasons.
That is a PITA when you’re sick working from home and need to do something on those servers.
Today this happened to me and looking for better alternatives than manually jumping to one of the boxes with access I’ve learned the SSH configuration &lt;em&gt;ProxyCommand&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This is how my ~/.ssh/config &lt;em&gt;Host&lt;/em&gt; configuration looked before:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Host client-qa01
  HostName 10.0.0.33
  IdentityFile ~/.ssh/keys/client/id_rsa_qa
  User client-qa
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is how it looks after &lt;em&gt;ProxyCommand&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Host client-qa01
  ProxyCommand ssh -W %h:%p jumpbox-host
  HostName 10.0.0.33
  IdentityFile ~/.ssh/keys/client/id_rsa_qa
  User client-qa
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;where &lt;em&gt;jumpbox-host&lt;/em&gt; is the machine with access to the client’s server.&lt;/p&gt;

&lt;p&gt;The command &lt;em&gt;ssh -W&lt;/em&gt; comes since OpenSSH 5.4 and works similarly to &lt;em&gt;netcat&lt;/em&gt;, it establishes an SSH tunnel between my local machine and &lt;em&gt;jumpbox-host&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;With this configuration instead of manually ssh’ing to &lt;em&gt;jumpbox-host&lt;/em&gt; and later ssh’ing to the target client server I can simply “ssh client-qa01” and SSH will transparently connect to the client’s server through &lt;em&gt;jumpbox-host&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Useful, huh? :)&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Nokogiri and Bundler</title>
   <link href="https://blog.tanob.me/2012/06/22/nokogiri-and-homebrew.html"/>
   <updated>2012-06-22T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2012/06/22/nokogiri-and-homebrew</id>
   <content type="html">&lt;p&gt;So you’re using &lt;a href=&quot;http://rubygems.org/gems/nokogiri&quot;&gt;Nokogiri&lt;/a&gt; and sometimes you’re getting a segmentation fault, that’s because Nokogiri likes to be run with new versions of libxml2. If you’re using &lt;a href=&quot;http://mxcl.github.com/homebrew/&quot;&gt;Homebrew&lt;/a&gt; to manage packages in OSX and &lt;a href=&quot;http://gembundler.com&quot;&gt;Bundler&lt;/a&gt; to manage your Ruby gems, you can get consistent installations of Nokogiri linked with the latest versions of libxml2 following these commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ brew install libxml2 libxslt
$ brew link libxml2 libxslt
$
$ prefix=$(brew --prefix)
$ bundle config build.nokogiri --with-xml2-include=$prefix/include/libxml2 --with-xml2-lib=$prefix/lib --with-xslt-dir=$prefix/include/libxslt
$ gem install nokogiri
$ nokogiri -v
# Nokogiri (1.5.4)
    ---
    warnings: []
    nokogiri: 1.5.4
    ruby:
      version: 1.9.3
      platform: x86_64-darwin11.4.0
      description: ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]
      engine: ruby
    libxml:
      binding: extension
      compiled: 2.8.0
      loaded: 2.8.0
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;http://gembundler.com/man/bundle-config.1.html&quot;&gt;bundle config&lt;/a&gt; allows you to set the configuration flags to be used when installing a gem through Bundler.&lt;/p&gt;

&lt;p&gt;Hope this helps you keep using Nokogiri without the segfault headaches :)&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>What you&#39;ll wish you&#39;d known</title>
   <link href="https://blog.tanob.me/2011/09/04/what-you-ll-wish-you-d-known.html"/>
   <updated>2011-09-04T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2011/09/04/what-you-ll-wish-you-d-known</id>
   <content type="html">&lt;p&gt;Quotes from &lt;a href=&quot;http://www.paulgraham.com/hs.html&quot;&gt;http://www.paulgraham.com/hs.html&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“…the closer you get to the truth, the messier your sentence gets.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;“You don’t see faces much happier than people winning gold medals. And you know why they’re so happy? Relief.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;“The most important thing is to be excited about it, because it’s by doing that you learn.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;“You start being an adult when you decide to take responsibility for your life. You can do that at any age.”&lt;/p&gt;
&lt;/blockquote&gt;

</content>
 </entry>
 
 <entry>
   <title>Git, please tell me commits that added a line containing $x</title>
   <link href="https://blog.tanob.me/2011/08/10/git-which-commits-added-line-containing.html"/>
   <updated>2011-08-10T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2011/08/10/git-which-commits-added-line-containing</id>
   <content type="html">&lt;p&gt;I was looking for a way in &lt;a href=&quot;http://mxcl.github.com/homebrew/&quot;&gt;homebrew&lt;/a&gt; to use an old version for a formula. Thanks to the fact that homebrew directory is actually a git repository, I could simply checkout an older version for the formula, I just needed to know which commit added support to the version I wanted. I’ve started naively with the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git log -S9.0.3 Library/Formula/postgresql.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The problem with this is that the “pickaxe” option will search for lines in commits that added or removed that string, but I’m only interested in commits that added the string. So I started looking for some command or option in git that would provide that. Unfortunately I couldn’t find anything so I decided to go on with an alias:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config alias.which-commits-added-line-containing \
    &#39;!f() { for sha1 in `git l -S$1 --format=%H`; do \
        (git show $sha1 | grep ^\+.*$1.*$ &amp;gt; /dev/null) &amp;amp;&amp;amp; echo $sha1; \
    done; }; f&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This alias, called &lt;code&gt;which-commits-added-line-containing&lt;/code&gt;, is defining a function that passes the first argument to the alias as the value for the &lt;code&gt;git log&lt;/code&gt; pickaxe option. For each of the commits that added or removed a line containing that string I will check using &lt;code&gt;grep&lt;/code&gt; if the string was added in that commit. &lt;code&gt;grep&lt;/code&gt; return status will be zero if it finds the pattern in the input so the command chaining (&amp;amp;&amp;amp;) will execute the &lt;code&gt;echo&lt;/code&gt; command that finally prints the commit’s SHA1 that added a line containing the string.&lt;/p&gt;

&lt;p&gt;Looks simple, doesn’t it? :)&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Robolectric and warnings about error binding shadow classes</title>
   <link href="https://blog.tanob.me/2011/07/22/robolectric-and-warnings-about-error-binding-shadow-classes.html"/>
   <updated>2011-07-22T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2011/07/22/robolectric-and-warnings-about-error-binding-shadow-classes</id>
   <content type="html">&lt;p&gt;If you are developing for Android and using &lt;a href=&quot;http://robolectric.org&quot;&gt;Robolectric&lt;/a&gt; in your unit-tests, depending on how you’re running them, you may get the following warnings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Warning: an error occurred while binding shadow class: ShadowGeoPoint
Warning: an error occurred while binding shadow class: ShadowItemizedOverlay
Warning: an error occurred while binding shadow class: ShadowMapController
Warning: an error occurred while binding shadow class: ShadowMapActivity
Warning: an error occurred while binding shadow class: ShadowMapView
Warning: an error occurred while binding shadow class: ShadowOverlayItem
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;in my case this was being caused because some of the classes in the Android SDK (android.jar) have dependencies in the Google API jars, this was simply solved adding them as dependencies in my project.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Trying again, now with Jekyll and GitHub</title>
   <link href="https://blog.tanob.me/2010/07/10/trying-again.html"/>
   <updated>2010-07-10T00:00:00+00:00</updated>
   <id>https://blog.tanob.me/2010/07/10/trying-again</id>
   <content type="html">&lt;p&gt;Here I am, trying again to document my experiments, problems and solutions.&lt;/p&gt;

&lt;h2 id=&quot;why-ive-gave-up-other-times&quot;&gt;Why I’ve gave up other times?&lt;/h2&gt;

&lt;p&gt;I mainly want to write about software development and all the blog engines that I tried in the past (Blogger, Wordpress) really suck when you try to put some code in your post.&lt;/p&gt;

&lt;p&gt;Of course this is not the only reason why I never had a very often updated blog. I really don’t have much extra time to write and for this reason I tend to only read from other people. I try to keep up with &lt;a href=&quot;http://twitter.com/tanob&quot;&gt;Twitter&lt;/a&gt;. I already tried to keep up with the feeds on Google Reader. I also have lots of interesting threads on the internal &lt;a href=&quot;http://thoughtworks.com&quot;&gt;ThoughtWorks&lt;/a&gt; mailing lists.&lt;/p&gt;

&lt;p&gt;But now let me try another way…&lt;/p&gt;

&lt;h2 id=&quot;github-and-the-jekyll-integration-aka-github-pageshttppagesgithubcom&quot;&gt;GitHub and the Jekyll integration (aka &lt;a href=&quot;http://pages.GitHub.com/&quot;&gt;GitHub Pages&lt;/a&gt;)&lt;/h2&gt;

&lt;p&gt;Thanks to GitHub and their integration with &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;Jekyll&lt;/a&gt; I can now write my posts using a simple text editor, commit and push to GitHub. They process all the files on your repository as soon as you push new files to it, serving them as static files.&lt;/p&gt;

&lt;p&gt;So far I only missed two things: a quick way to create a basic Jekyll skeleton; and a script to create the post following the filename convention (YYYY-MM-DD-post-title.markup). &lt;/p&gt;

&lt;p&gt;Currently I’m writing the posts using Markdown, but you can also use Textile or manually write HTML. My problem of having code within the post’s text is solved because &lt;a href=&quot;http://pygments.org/&quot;&gt;Pygments&lt;/a&gt; can be used to highlight them. I just need to wrap the source code snippet with a &lt;a href=&quot;http://wiki.GitHub.com/mojombo/jekyll/liquid-extensions&quot;&gt;&lt;em&gt;highlight&lt;/em&gt;&lt;/a&gt; block.&lt;/p&gt;

&lt;p&gt;A recent example that I have for how easy everything become when you are handling with plain text files is that my fiancee started her college’s monography, she is using MS Word to write it and was doing manual backup of the doc file. That made me remember of the time when I was writing my monography. I did use LaTeX and had all the advantages of text files. At that time I was not a git user, but I used &lt;a href=&quot;http://getdropbox.com&quot;&gt;Dropbox&lt;/a&gt; and had automatic backup every time that I saved a change to the file.&lt;/p&gt;

&lt;p&gt;Unfortunately handling with plain text files is not a solution to every kind of computer user, but for developers, it’s always a good idea to keep it simple!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Bookmarklet para Google Reader</title>
   <link href="https://blog.tanob.me/2008/12/09/bookmarklet-para-google-reader.html"/>
   <updated>2008-12-09T13:30:00+00:00</updated>
   <id>https://blog.tanob.me/2008/12/09/bookmarklet-para-google-reader</id>
   <content type="html">&lt;p&gt;Por algumas razões estou utilizando no dia-a-dia o Google Chrome (sim, ele não tem add-ons e é &lt;em&gt;extremamente&lt;/em&gt; 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:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;javascript:(function(){function fs(){var r=[];for(var i=0,ls=document.getElementsByTagName(‘link’);i&amp;lt;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&amp;gt;0)location.href=’http://fusion.google.com/add?feedurl=’+encodeURIComponent(ls[0].href);else alert(‘No feeds available!’);})()&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;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. Ah, se não sabe, Control+B mostra a barra de favoritos no Chrome.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>LINQ e SQL</title>
   <link href="https://blog.tanob.me/2008/10/01/linq-e-sql.html"/>
   <updated>2008-10-01T20:50:00+00:00</updated>
   <id>https://blog.tanob.me/2008/10/01/linq-e-sql</id>
   <content type="html">&lt;p&gt;Estava lendo uma das entrevistas da Computer World da série “The A-Z of Programming Languages”, sobre &lt;a href=&quot;http://www.computerworld.com.au/index.php/id;1149786074;pp;2&quot;&gt;a linguagem C#&lt;/a&gt;, e a parte abaixo me chamou a atenção:  &lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“[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]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No mesmo momento liguei a síntaxe SQL:  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nome&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pessoas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;WHERE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clausula&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;com a empregada no &lt;a href=&quot;http://en.wikipedia.org/wiki/LINQ&quot;&gt;LINQ&lt;/a&gt;:  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-sql&quot; data-lang=&quot;sql&quot;&gt;&lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nome&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pessoas&lt;/span&gt;  
&lt;span class=&quot;k&quot;&gt;where&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clausula&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  
&lt;span class=&quot;k&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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…  &lt;/p&gt;

&lt;p&gt;Isso demonstra o quão importante é o desenvolvimento da síntaxe da linguagem já pensando no que as ferramentas poderão auxiliar os desenvolvedores.  &lt;/p&gt;

&lt;p&gt;PS.: ando desaparecido por causa do &lt;a href=&quot;http://minerva.ufpel.edu.br/%7Emacarthy/nopcc/Proposta_Adriano.pdf&quot;&gt;meu trabalho de conclusão de curso&lt;/a&gt;, então entre trabalho e TCC não me sobra muito mais tempo além de ler alguns textos :)&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Programação dinâmica &amp; Concorrência</title>
   <link href="https://blog.tanob.me/2007/08/28/programao-dinmica-concorrncia.html"/>
   <updated>2007-08-28T03:11:00+00:00</updated>
   <id>https://blog.tanob.me/2007/08/28/programao-dinmica-concorrncia</id>
   <content type="html">&lt;p&gt;Como 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.  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-erlang&quot; data-lang=&quot;erlang&quot;&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ni&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ni&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;c&quot;&gt;% Start the Fibonacci Server with some basic pre-defined values...&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]).&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ReqPid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;ValueExists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;lists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;keymember&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;ValueExists&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{_,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;lists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;keysearch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
     &lt;span class=&quot;nv&quot;&gt;V&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;notFound&lt;/span&gt;
   &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;c&quot;&gt;% Send to the request process the atom notFound, or the Fibonacci of X.&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;ReqPid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;V&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;putValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ValueTuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ValueTuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;c&quot;&gt;% Ask the server for the Fibonacci of N...&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;fibServer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt;
  &lt;span class=&quot;c&quot;&gt;% If the value doesn&amp;#39;t exist yet, then...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;notFound&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;c&quot;&gt;% ...calculate it...&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;FibN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
   &lt;span class=&quot;c&quot;&gt;% ...update the server with this new value...&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;fibServer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;putValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;FibN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}},&lt;/span&gt;
   &lt;span class=&quot;c&quot;&gt;% ...return the calculated value.&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;FibN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;X&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
   &lt;span class=&quot;c&quot;&gt;% The value was already in the server.&lt;/span&gt;
   &lt;span class=&quot;nv&quot;&gt;X&lt;/span&gt;
 &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
 &lt;span class=&quot;c&quot;&gt;% Just start the process identified by the atom &amp;#39;fibServer&amp;#39;,&lt;/span&gt;
 &lt;span class=&quot;c&quot;&gt;% as the execution of the fibserver:fibserver/0,&lt;/span&gt;
 &lt;span class=&quot;c&quot;&gt;% that means, module fibserver, function fibserver&lt;/span&gt;
 &lt;span class=&quot;c&quot;&gt;% that receives zero parameters.&lt;/span&gt;
 &lt;span class=&quot;nb&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fibServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;spawn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fibserver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])).&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Coloquei alguns comentários, mas para o total entendimento do código, você deve ter uma &lt;a href=&quot;http://erlang.org/doc/getting_started/part_frame.html&quot;&gt;noção básica&lt;/a&gt; sobre Erlang, qualquer dúvida só postar.&lt;/p&gt;

&lt;p&gt;Para testar:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ erl  
Erlang (BEAM) emulator version 5.5.2 [source] [async-threads:0] [kernel-poll:false]  

Eshell V5.5.2 (abort with ^G)  
1&amp;gt; c(fibserver).  
{ok,fibserver}  
2&amp;gt; fibserver:start().  
true  
3&amp;gt; fibserver:fib(1000).  
43466557686937456435688527675040625802564660517371780402481729089536555417949051890403879840079255169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875  
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;O resultado é praticamente instantâneo :)  &lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;halt()&lt;/code&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Brincando com Erlang</title>
   <link href="https://blog.tanob.me/2007/08/22/brincando-com-erlang.html"/>
   <updated>2007-08-22T04:30:00+00:00</updated>
   <id>https://blog.tanob.me/2007/08/22/brincando-com-erlang</id>
   <content type="html">&lt;p&gt;Ultimamente tenho visto &lt;a href=&quot;http://del.icio.us/tanob/erlang&quot;&gt;muitos posts&lt;/a&gt; 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.&lt;/p&gt;

&lt;p&gt;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 &lt;a href=&quot;http://erlyweb.org/&quot;&gt;framework web&lt;/a&gt; e um &lt;a href=&quot;http://www.erlang.org/doc/apps/mnesia/index.html&quot;&gt;banco de dados&lt;/a&gt; super escalável!&lt;/p&gt;

&lt;p&gt;Para começar, instalei o pacote “erlang” no Debian Etch, muito simples.&lt;/p&gt;

&lt;p&gt;Então vamos para nosso primeiro programa, “hello world” ou Fibonacci? Ok, ok…&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Crie um arquivo chamado hello.erl, com o seguinte código:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt; -module(hello).  
 -export([hello/0]).  

 hello() -&amp;gt; io:format(&quot;Hello world!~n&quot;).
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;Chame o interpretador Erlang com o comando “erl”;&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Compile o programa:  &lt;/p&gt;

    &lt;pre&gt;&lt;code&gt; c(hello).
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;Isto deve gerar um aviso &lt;code&gt;{ok, hello}&lt;/code&gt;;&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Vamos executar:  &lt;/p&gt;

    &lt;pre&gt;&lt;code&gt; hello:hello().
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;Pronto, satisfeito?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;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:  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-erlang&quot; data-lang=&quot;erlang&quot;&gt;&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ni&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;ni&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;  

&lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Reparem que há um pattern matching nos 2 casos básicos, e após a implementação recursiva para qualquer N &amp;gt; 1, com base disso podemos diminuir um pouco o código:  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-erlang&quot; data-lang=&quot;erlang&quot;&gt;&lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  
&lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;N&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A chamada desde código após a compilação é trivial, por exemplo:  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-erlang&quot; data-lang=&quot;erlang&quot;&gt;&lt;span class=&quot;nn&quot;&gt;fibonacci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fib&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;O código em Haskell é muito semelhante (como não seria com esse pingo de código? :D)  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-erlang&quot; data-lang=&quot;erlang&quot;&gt;&lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;  
&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;otherwise&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fib&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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.  &lt;/p&gt;

&lt;p&gt;Finalizo por aqui, e &lt;a href=&quot;http://home.hiwaay.net/%7Ejalison/Fib500.html&quot;&gt;clique aqui&lt;/a&gt; se quiser conferir a lista dos 500 primeiros valores para a série de Fibonacci.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Que linguagem você é?</title>
   <link href="https://blog.tanob.me/2007/05/01/que-linguagem-voc.html"/>
   <updated>2007-05-01T05:24:00+00:00</updated>
   <id>https://blog.tanob.me/2007/05/01/que-linguagem-voc</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.bbspot.com/News/2006/08/language_quiz.php&quot;&gt;&lt;img src=&quot;http://www.bbspot.com/Images/News_Features/2006/08/language/php.jpg&quot; alt=&quot;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.&quot; /&gt;&lt;br /&gt;
Which Programming Language are You?&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Pô!!! PHP?!?! Sacanagem… :)  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Vi isto no &lt;a href=&quot;http://devlog.waltercruz.com/que_linguagem_voce_e&quot;&gt;blog do Walter Cruz&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Olá via FeedBurner</title>
   <link href="https://blog.tanob.me/2007/04/24/ol-via-feedburner.html"/>
   <updated>2007-04-24T04:09:00+00:00</updated>
   <id>https://blog.tanob.me/2007/04/24/ol-via-feedburner</id>
   <content type="html">&lt;p&gt;Adeus aos feeds não rastreáveis do blogger :D  &lt;/p&gt;

&lt;p&gt;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.  &lt;/p&gt;

&lt;p&gt;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 &lt;em&gt;tracking&lt;/em&gt; 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.  &lt;/p&gt;

&lt;p&gt;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.  &lt;/p&gt;

&lt;p&gt;Para seguir a filosofia &lt;acronym title=&quot;Don&#39;t Repeat Yourself&quot;&gt;DRY&lt;/acronym&gt;, editei o template do blog para não disponibilizar o feed que o Blogger provê. Para fazer isto vi que existe uma tag &lt;code&gt;&amp;lt;b:include data=&quot;&#39;blog&#39;&quot; name=&quot;&#39;all-head-content&#39;&quot;/&amp;gt;&lt;/code&gt; entre o &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; e o &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt;, esta tag é depois substituida por tags &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; e &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt;. Apenas substitui esta tag pelo código gerado por ela, substituídos os &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; relacionados a feed RSS/Atom dos posts pelo &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; oferencendo feed Atom do FeedBurner.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Concordo: IE6 deve morrer</title>
   <link href="https://blog.tanob.me/2007/04/16/concordo-ie6-deve-morrer.html"/>
   <updated>2007-04-16T01:41:00+00:00</updated>
   <id>https://blog.tanob.me/2007/04/16/concordo-ie6-deve-morrer</id>
   <content type="html">&lt;p&gt;&lt;em&gt;Como o Blogger não suporta Trackback ainda, então vai na mão mesmo:&lt;br /&gt;
&lt;a href=&quot;http://www.tableless.com.br/ie6-deve-morrer&quot;&gt;http://www.tableless.com.br/ie6-deve-morrer&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Na última sexta-feira, &lt;a href=&quot;http://en.wikipedia.org/wiki/Friday_13&quot;&gt;13&lt;/a&gt; por coincidência, tive 2 dores de cabeça com o IE6.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problema #1&lt;/strong&gt;: um Javascript responsável por salvar alguns dados no servidor:  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;country&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;countries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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 &lt;em&gt;var&lt;/em&gt; ali na declaração de &lt;em&gt;country&lt;/em&gt;”. Dito e feito, o correto é:  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;country&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;countries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Problema #2:&lt;/strong&gt; 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 &lt;em&gt;flickering&lt;/em&gt;. Pesquisando vi que isso já é um bug conhecido do IE6, &lt;a href=&quot;http://www.fivesevensix.com/studies/ie6flicker/&quot;&gt;uma página&lt;/a&gt; fazia uma série de teorias explicando o porque daquele bug, &lt;a href=&quot;http://plone.org/documentation/how-to/flickering-background-images-internet-explorer&quot;&gt;outra&lt;/a&gt; apenas relatava a solução que foi adotada, a &lt;a href=&quot;http://www.brunildo.org/test/IEAbackima.html&quot;&gt;terceira e última&lt;/a&gt; foi mais útil, explica que a causa do problema está nos &lt;em&gt;response headers&lt;/em&gt; HTTP, mais precisamente no &lt;em&gt;Expires&lt;/em&gt;. 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:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!--[if IE 6]&amp;gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;try {&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;document.execCommand(&amp;quot;BackgroundImageCache&amp;quot;, false, true);&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;} catch(err) {}&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;&amp;lt;/script&amp;gt;&amp;lt;![endif]--&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Solucionado! Muito melhor que perder tempo² (meu tempo desenvolvendo uma solução para retornar as imagens com o header &lt;em&gt;Expires&lt;/em&gt;, 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).&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>My nerd score</title>
   <link href="https://blog.tanob.me/2007/04/13/my-nerd-score.html"/>
   <updated>2007-04-13T23:17:00+00:00</updated>
   <id>https://blog.tanob.me/2007/04/13/my-nerd-score</id>
   <content type="html">&lt;p&gt;Como vi outros nerds mostrando seus scores, então aqui está:  &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.nerdtests.com/ft_nq.php?im&quot;&gt;&lt;img src=&quot;http://www.nerdtests.com/images/ft/nq.php?val=5771&quot; alt=&quot;I am nerdier than 90% of all people. Are you nerdier? Click here to find out!&quot; /&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;Tinha feito este teste há algum tempo atrás e lembro que meu score foi 84, que evolução! :D&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Lições relacionadas a Javascript</title>
   <link href="https://blog.tanob.me/2007/04/08/lies-relacionadas-javascript.html"/>
   <updated>2007-04-08T07:04:00+00:00</updated>
   <id>https://blog.tanob.me/2007/04/08/lies-relacionadas-javascript</id>
   <content type="html">&lt;p&gt;Trabalhando com Javascript e “Ajax” em um projeto tomei as seguintes lições:  &lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Opera 8.5 não lida bem com respostas cujo mime-type é ‘application/json’, a solução foi atualizar para a 9.0;  &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;IE não gosta de vírgulas extra em suas matrizes, por exemplo &lt;code&gt;[1,2,3,]&lt;/code&gt;, ele interpreta aquela última vírgula como um outro elemento da matriz;  &lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Usando as facilidades “Ajax” do jQuery, caso ocorra uma exceção dentro da callback de success, o jQuery irá chamar a callback de error;&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>JQuery, CSS e ids (X)HTML</title>
   <link href="https://blog.tanob.me/2007/03/24/jquery-css-e-ids-xmd.html"/>
   <updated>2007-03-24T15:02:00+00:00</updated>
   <id>https://blog.tanob.me/2007/03/24/jquery-css-e-ids-xmd</id>
   <content type="html">&lt;p&gt;Em um projeto que estou trabalhando no momento estou usando o &lt;a href=&quot;http://jquery.org/&quot;&gt;JQuery&lt;/a&gt;, porém me deparei com um problema ao tentar utilizar o seu &lt;code&gt;$()&lt;/code&gt; com elementos que contenham ids com caracteres como ponto e dois-pontos, que são &lt;a href=&quot;http://www.w3.org/TR/html401/types.html#type-id&quot;&gt;caracteres válidos em ids&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;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 &lt;a href=&quot;http://dev.jquery.com/ticket/143&quot;&gt;bug report para este problema&lt;/a&gt; (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…  &lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;#test&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;.x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;background-color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;green&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;yellow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;  
...  
&lt;span class=&quot;nt&quot;&gt;&amp;lt;p&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;test.x&amp;quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;P with id &amp;#39;test.x&amp;#39;.&lt;span class=&quot;nt&quot;&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;O código acima não irá funcionar como esperado, ele na verdade seleciona o elemento com id &lt;code&gt;test&lt;/code&gt; e classe &lt;code&gt;x&lt;/code&gt;, para ter o efeito desejado deve-se usar &lt;code&gt;#test\.x&lt;/code&gt;, ou seja, “escapa”-se o ponto, o que informa ao interpretador CSS para cancelar a busca pela classe.  &lt;/p&gt;

&lt;p&gt;A solução temporária é eu aplicar o patch e compilar a minha própria versão do JQuery…&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Ano novo copyright velho?</title>
   <link href="https://blog.tanob.me/2007/03/19/ano-novo-copyright-velho.html"/>
   <updated>2007-03-19T04:56:00+00:00</updated>
   <id>https://blog.tanob.me/2007/03/19/ano-novo-copyright-velho</id>
   <content type="html">&lt;p&gt;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…  &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://bp3.blogger.com/_GXBR7ak83lI/Rf4ZDAjnyvI/AAAAAAAAADg/lBDus0nJsnY/s1600-h/gmail_externa.png&quot;&gt;&lt;img src=&quot;http://bp3.blogger.com/_GXBR7ak83lI/Rf4ZDAjnyvI/AAAAAAAAADg/lBDus0nJsnY/s320/gmail_externa.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;… enquanto na interna:  &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://bp0.blogger.com/_GXBR7ak83lI/Rf4ZZQjnyxI/AAAAAAAAADw/VORi4DH7LKM/s1600-h/gmail_interna.png&quot;&gt;&lt;img src=&quot;http://bp0.blogger.com/_GXBR7ak83lI/Rf4ZZQjnyxI/AAAAAAAAADw/VORi4DH7LKM/s320/gmail_interna.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;PS.: a qualidade desse htmlarea do blogger é péssima²³ (olha só, agora estou aqui no Jekyll… :-))&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>OpenSearch</title>
   <link href="https://blog.tanob.me/2007/03/19/opensearch.html"/>
   <updated>2007-03-19T02:35:00+00:00</updated>
   <id>https://blog.tanob.me/2007/03/19/opensearch</id>
   <content type="html">&lt;p&gt;Finalmente tive um tempo para olhar a especificação do &lt;a href=&quot;http://www.opensearch.org/&quot;&gt;OpenSearch&lt;/a&gt; e aproveitei para implementar uma descrição para o &lt;a href=&quot;http://www.mininova.org/&quot;&gt;Mininova.org&lt;/a&gt;, 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 ;)  &lt;/p&gt;

&lt;p&gt;A implementação está &lt;a href=&quot;http://minerva.ufpel.edu.br/%7Eadrianob_ifm/opensearch/&quot;&gt;aqui&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>An Inconvenient Truth</title>
   <link href="https://blog.tanob.me/2007/01/21/inconvenient-truth.html"/>
   <updated>2007-01-21T19:16:00+00:00</updated>
   <id>https://blog.tanob.me/2007/01/21/inconvenient-truth</id>
   <content type="html">&lt;p&gt;Ó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”.  &lt;/p&gt;

&lt;p&gt;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.  &lt;/p&gt;

&lt;p&gt;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.  &lt;/p&gt;

&lt;p&gt;Frase do filme: “É difícil fazer um homem entender algo se seu salário depender de seu não entendimento.” (“&lt;em&gt;It is difficult to get a man to understand something when his salary depends upon his not understanding it.&lt;/em&gt;”)  &lt;/p&gt;

&lt;p&gt;Outro filme que vi este final de semana e que gostei muito é &lt;em&gt;Lord of War&lt;/em&gt; (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.  &lt;/p&gt;

&lt;p&gt;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.”  &lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://omedi.blogspot.com/2007/01/cinema-o-filme-mais-assustador-de.html&quot;&gt;Dica do “&lt;em&gt;An Inconvenient Truth&lt;/em&gt;” veio do OMEdI.&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Easter eggs open-source</title>
   <link href="https://blog.tanob.me/2006/11/23/easter-eggs-open-source.html"/>
   <updated>2006-11-23T15:18:00+00:00</updated>
   <id>https://blog.tanob.me/2006/11/23/easter-eggs-open-source</id>
   <content type="html">&lt;p&gt;Nã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 &lt;a href=&quot;http://www.eeggs.com/items/48349.html&quot;&gt;Notepad&lt;/a&gt; entre alguns outros.  &lt;/p&gt;

&lt;p&gt;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 &lt;a href=&quot;http://www.noticiaslinux.com.br/nl1164246954.html&quot;&gt;link&lt;/a&gt; com alguns casos, dentre eles um que eu não me lembrava, o do “moo” no apt-get.&lt;br /&gt;
Me lembrei agora há pouco de um no &lt;a href=&quot;http://www.eeggs.com/items/18686.html&quot;&gt;PHP&lt;/a&gt;, e claro, o do “import this” do Python (&lt;a href=&quot;http://www.python.org/dev/peps/pep-0020/&quot;&gt;The Zen of Python&lt;/a&gt;).  &lt;/p&gt;

&lt;p&gt;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 :D&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Tá meio apertado aqui não?</title>
   <link href="https://blog.tanob.me/2006/10/28/t-meio-apertado-aqui-no.html"/>
   <updated>2006-10-28T18:16:00+00:00</updated>
   <id>https://blog.tanob.me/2006/10/28/t-meio-apertado-aqui-no</id>
   <content type="html">&lt;p&gt;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 &lt;a href=&quot;http://en.wikipedia.org/wiki/Lvm&quot;&gt;LVM&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;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).&lt;/p&gt;

&lt;p&gt;Formatei as partições com o &lt;a href=&quot;http://en.wikipedia.org/wiki/Xfs&quot;&gt;XFS&lt;/a&gt;, pois já estava pensando que no futuro, quando necessário, este sistema de arquivos me facilitaria a vida ao estender os volumes lógicos…&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# lvextend -L+5G /dev/data_vg/misc_lv&lt;/span&gt;
File descriptor &lt;span class=&quot;m&quot;&gt;11&lt;/span&gt; left open
Extending logical volume misc_lv to 20,00 GB
Logical volume misc_lv successfully resized

&lt;span class=&quot;c&quot;&gt;# xfs_growfs /var/misc&lt;/span&gt;
xfs_growfs: XFS_IOC_FSGROWFSDATA xfsctl failed: Não há espaço disponível no dispositivo&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Oh-oh! Falta de espaço?! Claro né, porque que estou dando um resize então?!
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…&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# xfs_growfs /var/misc&lt;/span&gt;
data blocks changed from &lt;span class=&quot;m&quot;&gt;3932160&lt;/span&gt; to 5242880&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Shazam! Na hora, sem desmontar, sem reiniciar o computador, sem parar nenhuma aplicação, aumentou minha partição para 20GB:&lt;/p&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# df -h | grep misc&lt;/span&gt;
/dev/mapper/data_vg-misc_lv 20G 15G 5,1G 75% /var/misc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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 :D&lt;/p&gt;

</content>
 </entry>
 
 
</feed>

