Tuesday, April 7, 2009

How to Avoid Cell Phone Spam

Recently I've noticed a definite upswing in the number of unsolicited commercial phone calls I get on my cell phone. What to do?

I found a simple may to minimize (or at least reduce) the annoyance. My phone uses mp3 files for custom ringtones, and is able to receive such files via email. So I

  • edited a silent and extremely short mp3 file

  • sent it to my phone

  • saved the annoying caller as a contact, and

  • set the custom ringtone for that contact to the silent file



It requires a little overhead in defining the contact, but now it means that I am no longer bothered by that caller again.

Thursday, March 26, 2009

Constant Hashes w/defaults in Ruby

Hi there. I'm back after a long hiatus. Since my last post, I've moved across the country from Buffalo, NY to Berkeley, CA, had 2 jobs, and become a father. So I ask your forgiveness for the long period between posts.

On to some code. I like to use Constants in Ruby whenever feasible. It's a logical and readable-to-the-next-coder way to store information in a way that indicates it should not change. It also gets some compile-time optimization for speed, and takes up less memory as a datum shared across the various instances of a class.

I'm particularly fond of constant Hashes for small lookup tables. Let's imagine some generic Rails controller with this code snippet:

BANAL_MESSAGE_FOR = {
:edit => 'You are editing.',
:show => 'You are viewing a single instance.'
}


Hashes in Ruby have a handy method called default= that sets what the default looked-up value should be when the key for the lookup is not found in the Hash. (You can think of the default default as nil, if that makes any sense.) However, default= returns the default value, rather than the new Hash. So this gets problematic:


BANAL_MESSAGE_FOR = {
:edit => 'You are editing.',
:show => 'You are viewing a single instance.'
}.default = "I don't know what you're doing".


The example above will break, as BANAL_MESSAGE_FOR is no longer a Hash at all.


BANAL_MESSAGE_FOR = {
:edit => 'You are editing.',
:show => 'You are viewing a single instance.'
}
BANAL_MESSAGE_FOR.default = "I don't know what you're doing".


The example above will lead to compile-time warnings about modifying a Constant.

What alternatives exists for this issue?



I've grown fond of the following approach:

BANAL_MESSAGE_FOR = lambda do
message_for = {
:edit => 'You are editing.',
:show => 'You are viewing a single instance.'
}
message_for.default = "I don't know what you're doing".
message_for
end.call


This allows us to define the particular cases with explicit Hash pairs, set a default value, and keep everything in Constant world. Depending on the particulars, we could instead go with either a class variable (@@banal_message_for) or a class method.

I still like constant-from-a-lambda, though - even despite the somewhat off-putting complexity of the lambda/call syntax. It makes it clear that we're dealing with constant data, and the complexity from the call syntax seems less egregious to me than having an additional method whose only purpose is to be called once at app start.

What do you think?