Quick debugger tip in Ruby

The ruby-debug gem is great for debugging but here’s something you might have missed: you can call it with a condition. That way it only breaks execution when a given condition is met.


[3, 2, 15, nil, 5].collect do |id|

  debugger if id.nil?

  id.to_s

end

That way, it will only stop if one of the array items is nil. This is a huge time-saver. Use it frequently.

Netbeans 6.5 Code folding and test files

I don’t know how many people will find this useful, but it made me lose some time, so that’s why I’m sharing.
I use Netbeans code folding and the Shoulda plugin by Thoughtbot. Today I ran into this strange situation where Netbeans wasn’t showing the folds for one of my files, but it did for the others.
The reason why no folds were appearing in one of the files was that its name didn’t end in ‘_test.rb’. I changed it and the ‘context’ and ‘should’ code folds appeared.
That was pretty annoying, but good thing I found out.

5 Mind-blowing firebug secrets

I spent my whole workday using Firebug, so discovering these was a huge productivity improvement for my workflow. Enjoy:

The power of Ctrl-Z
If you use Firebug console with the larger command line and you change tabs, the content of what you had typed gets erased. In the smaller command line you get what you previously entered by hitting the up arraw. In the larger command line this doesn’t work, but if you hit Ctrl-Z you’ll be able to go back through the history of what you typed. Pretty Awesome. You can even close the tab or open the console in a new one and it will still remember.
tip1
Programmatic Debugger
Being able to place breakpoints using the debugger in the script tab is pretty awesome, but if you need more flexibility (say, stop everytime a loop is run) you can use the debugger keyword inside your JS code and it will break every time it’s called, then you only have to hit play to resume until the next breakpoint
tip2
Legibility in the Console
If, for example, you have a long chunk of HTML code that you are appending to a node, it might be easier to indent it, but because it’s wraped in quotes you’ll get an “unterminated string literal” error. A solution to this is using backslashes (“\”) to indicate a line break. Just be sure to not leave any spaces to the right of the backslash.

Remember also, that you can use regular JS comments (“//”, “/**/”) in the console. This can be useful for quick toggling of certain lines

tip3

Docking to the Right
There is a great Firefox addon called Widerbug which allows you to dock Firebug to the right of your screen. I know it’s been around for some time, but I only found about it today, so that’s why I’m including it. The only problem I have with it is that once you select the Firefox tab where Widerbug is running it squishes the other tabs to the left, and I find it kind of annoying, but it’s a great way to use your widescreen monitor’s real estate
tip4
Messages From Your Code
Do yourself a favor and stop using the alert() call to debug your app, if you still are. A much more legible way is using console.info(). There are other varieties like console.log(), console.error(), etc., but I like the blue “i” this one shows.

Also, remember you can insert as many things as you want in a single message, so instead of doing this

console.info("My array has " + arr.length + " items")//notice the spaces

You should be doing this:

console.info("My array has", arr.length, "items", "look:", arr)

tip51

Happy coding, and tell me if you’ve found these useful.

Note: As of this writing I’m using Firebug 1.3.0b7

Bonus tip: Install the Monaco font, it’s so much nicer and Courier New.

jQuery (QUnit): sharing variables between tests in different modules

I went crazy for a few days trying to find out how to share variables between my tests in QUnit. If anybody knows of a better way, please share. This is an example of how to share the variable $phrases between two tests in two different modules:

$(document).ready(function () {
  //variables you want to share.
  var $phrases = $("#phrases li")

  module("Attributes:");
  test("trying out text():", function() {
    same($phrases.eq(0).text(), "myText");
  };
  module("Traversing:");
  test("trying out contents()", function() {
    same($phrases.eq(2).contents(), "<#text></#text>")
  };
});

jQuery: $.extend() and $.fn.extend() confusion

There is a significant difference between using .extend() with one argument and doing it with two or more:

When .extend() receives a single object, it adds the methods defined in it to either the jQuery or the jQuery.fn (also called jQuery.prototype and $.fn) objects.

As a general rule, you should extend the jQuery object for functions and the jQuery.fn object for methods. A function, as opposed to a method, is not accessed directly from the DOM.

Notice the different way of calling a method when extending the jQuery.fn or jQuery objects. The receiver (what’s to left of the period) changes.

$.fn.extend({
myMethod: function(){...}
});
//jQuery("div").myMethod();

$.extend({
myMethod2: function(){...}
});
//jQuery.myMethod2();

When .extend() receives two or more objects, it takes the first object and adds to it the methods and variables defined in the other objects. See an example:

defaults = { size: 3 };
options = { height: 6 };
var opts = $.extend(defaults, options)
// 'defaults' receives the methods and variables defined in 'options'
// opts == defaults == { size: 3, height: 6 }
// options == { height: 6 };

If the first object is empty, it will add the methods and variables in a new object. This is useful when we want to group the methods defined in several objects without modifying any of them:

<pre>var opts = $.extend( {}, defaults, options)
// 'opts' gets all methods and variables defined in 'defaults' and 'options',
// neither of them get modified.
// opts == { size: 3, height: 6 }
// defaults == { size: 3 };
// options == { height: 6 };

Attribute_fu: has_many_without_association_option’: stack level too deep

If you’re getthing this error, it’s probably because you have a /stable directory that got created while you were trying to install the plugin. So check that you only have /vendor/plugins/attribute_fu and not vendor/plugins/stable.

Also, if you want to install attribute_fu but using piston doesn’t work, try this:

svn checkout http://svn.jamesgolick.com/attribute_fu/tags/stable vendor/plugins/attribute_fu

Happy nesting!

RESOLVED: ActiveRecord::StatementInvalid: SQlite3::SQLException: SQL logic error or missing database

1) Delete any fixtures located in test/fixtures.
2) Solved.

The startup

I’m determined to gracefully quit my job so I can stop working to get paid and start getting paid for doing what I like. My passions right now are languages and web design, so what better way to do it than by launching a startup?

I’m building an application to see how other people learn a foreign language; this provides a significant advantage because the learner can build on top of what others have already found useful. It is done by allowing each user to write down what they find difficult about the language as well as the information that helps them understand it in a personal notebook. All the notebooks are shared, and instead of finding out how to understand a particular difficulty, a user can just see how another person solved the problem. Moving from difficulty to difficulty is the best way to explore the language, improve motivation and guarantee true learning.

I’m on the initial stages of the application and in order to do it properly I would need two partners to help me with the design and the coding (Ruby on Rails). If anybody is interested drop me a line at nachocab at) gmail dot com.

There is a single place for everything

my old to-do list

I just finished watching Merlin Mann’s Inbox Zero Talk and I realized that the reason why my initial attempt to integrate language learning with my daily to-do list had failed (the picture is just an extract from my 300 item list at todoist. I was mixing the things that I needed to get done (ACTION) with the words that I needed to study (LEARN). If there is a single place for everything, acting and learning should never go together. The only moment where action is related to learning is when you actually decide that you have to start studying. But once you have initiated this action, what you need is a proper environment for learning.

This is definitely not a to-do list. I still have to figure out what it will be, but it will probably be called asimilia 😉

Balancing my day job, my app and my blog

My original resolution of writing 5 times a week is proving to be quite unrealistic :). I work from 9:30 to 18:30, so the only time I have left is 5 hours between 19:00 and midnight. This would appear to be a decent amount of time but, even if I sit down in front of the computer as soon as I get back from work, it never feels like I accomplish much. If on top of this I have to do some other kind of chore (e. g. cooking, laundry, sweeping, mopping and a long etcetera) time literally flies. I doubt it’s a lack of GTD discipline, but I’ll keep it in mind.

Yesterday was a very productive day in particular. The electricity in my house went out and, even though I was surprised that anybody worked in France on a Sunday afternoon, somebody from EDF eventually came to fix it. The rest of the day I spent downgrading Rails from 2.0.2 to 1.2.6 because I got tired of not being able to follow Ryan’s Railscasts. A very productive day, indeed.

Anyway, on Thursday I’m going on vacation to Brazil and that means +7 days to the first release date. Naturally, in this case, I think it’s worth it.IpanemaIpanema

When learning a language stops being a linear experience

During the first year of high school Spanish the average student learns around 400 new words and expressions in only a few months. Many of these words are learned without an incredible amount of effort from the student’s part. This is a pretty good number if we consider that classes are an average of 40 minutes long and filled with inattentive teenagers. This shows that vocabulary learning at the early stages is a linear process: if you put in an average amount of effort, you will get a decent retention rate in result.After we learn enough words—around 1,000 for Spanish—the learning curve goes up exponentially. The amount of time we put in is no longer proportional to the number of words we can remember. This is because the way most people learn new words is by repeated exposure. We don’t go running to the dictionary every time we hear a word that we are not familiar with. But if we hear it three or four times, we might actually look it up. The same holds true for learning words in a foreign language: the words that get learned first are those that get repeated the most. When the percentage of repetition gets too low–that is, when we don’t get to see or hear the word very often– it keeps getting harder and harder to find the motivation to actually pick up the dictionary and look it up. Especially if the meaning can be guessed from the context.

This means that if we found a way to give more focus to less frequently repeated words, we could still learn them as fast as we did in the beginning. This is what I am currently working on: decreasing the difficulty bump that comes after the initial stages of the learning process.

The first step

This is the most important step, so I’ll make it short but to the point. I love learning languages and I want to share what I know so other people can benefit from it. Eventually, I’d like to make this my day job. But in order to do that I need to:

  1. Create a revolutionary product that others can use to learn languages.
  2. Gather a community of people around it.
  3. Quit my current day job.

This is the plan (at least I have a plan). Step one: done! The journey has begun 🙂