魔杰夫-‘思想不成熟的’和狗不得进入

October 31, 2007

Facts About the Most Prolific Species On The Earth

Filed under: Knowledge — jfree @ 5:23 pm
  • The combined weight of the earth’s ants outweighs that of humans, and they have the highest population of any animal on earth.
  • They are prolific: the only places without an indigenous ant population are Antarctica, Greenland, Iceland and a handful of remote tropical islands.
  • Ants know how to look after their monarchs. A queen ant can live for up to 30 years, while male workers generally survive for only a few weeks.
  • African driver ants are so vicious they have been known to kill humans. Although cases are rare, babies or already unconscious adults are occasionally found killed by the creatures, which attack in swarms of up to 100,000.
  • There are more than 12,000 different species of ant, ranging in size from 2mm to 25mm (about an inch).
  • They are surprisingly strong and fast. Ants can lift 20 times their own body weight and run so fast that if we could move as quickly for their size as ants, then we would be as fast as racehorses.
  • Ants cannot actually chew or swallow their food. Instead they squeeze out the juice.
  • They have two stomachs: one for their own food, and one for other ants in the colony.
  • Ants are remarkably tidy. Some worker ants take on the job of taking the nest’s waste to an outside rubbish dump.

Powered by ScribeFire.

October 30, 2007

STOP Your Negative Thoughts

Filed under: Own Production, Self-improvement, Tech — jfree @ 11:10 am

“What we focus on, we empower and enlarge. Good multiplies when focused upon. Negativity multiplies when focused upon. The choice is ours: Which do we want more of?”
- Julia Cameron

Negative thinking can make all sorts of things incredibly difficult. It is like a leak in your confidence bucket – constantly drip-drip-dripping away your confidence and self esteem. At the same time, it will sabotage your self belief and your achievements too. And we need to know that negative thoughts are not reserved for just a few people or situations. Everyone is plagued by negative thoughts at one time or another.

Research shows that people who receive positive distractions for just eight minutes show a remarkable change in their moods and in breaking the cycle of repetitive thought. So, next time you catch yourself repeating the same negative thoughts over and over in your mind, use the STOP acronym:

1. S – Say the word STOP!
Interrupt your internal destructive thoughts. Tell yourself firmly to “STOP” over thinking. Be strict, and don’t let them intrude on your thoughts. It also might be helpful to visualize a box to place all your negative thoughts in, which you may open at a later date or time.

2. T – TAKE a break!
Take a deep breath. Then, take a break. Go for a walk or a hike, read a great book, listen to your favorite music. Do something to take your attention away from over thinking, and if possible, change the environment.

3. O – Focus on the OUTCOME!
Focus on the OUTCOME of your goals. Affirm why you are committed to your goals. The way we feel and what we experience in our body comes from what we focus our attention upon during a given moment. And at any moment, we are “deleting” most of what is going on around us. That is, to feel bad, we have to delete (not focus on, not think about) everything that’s great in our life. And vice versa. For us to feel good, we have to delete the things we could feel bad about.

4. P – PRAISE yourself!
PRAISE and acknowledge yourself for the progress you are making. Remember, you’re looking for progress, not perfection! Give yourself a reward every time you’re successful with overcoming negative thoughts.

Remember, you are what you think!

Powered by ScribeFire.

October 26, 2007

Trick to Change “Ready” Message on HP Printers

Filed under: Own Production, Tech — jfree @ 9:57 am

Amazed your colleagues with a weird message on the office printer using the HP Printer Job Language (HPPJL) command set. Here is how you do that:

First we need to know the IP address of your HP printer. You can always go to ‘Printers and Faxes’ which resides on ‘Control Panel’. From there you can see all of the printers that are interconnected with your workstation. What you do next is right click on the HP printer that you would like to ‘hack’ into, then choose ‘Properties’. Go to ‘Ports’ tab, then click on ‘configure port’ button. From there you should be able to see the IP address of the printer and not to forget the port number. The default port used by HP printers is 9100.

Now you get the IP address and Port number that you want. Thereafter you can use a remote telnet console like PuTTY to telnet to the address. Let’s start our magical work from here:

jeff@mymachine [501]$ telnet 192.168.120.101 9100
Trying 192.168.120.101…
Connected to 192.168.120.101.
Escape character is ‘^]’.
^P^[%-12345X@PJL RDYMSG DISPLAY="HEY, YOU ARE THE BEST!"
%-12345X
^]
telnet> quit
Connection closed.

That’s it and you should be able to see changes on your HP printer display screen from “Ready” to your desired message, whatever it is.

Now not to forget to cover your ass. What if your boss discover that and ask you to change it back to normal? Well, it is relatively easier and take just 2 magical touches.
1. Turn off the power switch.
2. On it again.
So the easiest solution is Power-cycle your printer. The program uses a documented, supported feature of HP’s product to do something very ephemeral and undoing it is as easy as a restart.

Even little trick: To get the escape character at the beginning of each line, press CTRL-P then ESC.

Powered by ScribeFire.

October 24, 2007

The Unwillingness Within Me That I Never Realise

Filed under: Own Production — jfree @ 5:16 pm

At times I complain that God is not with me when I meet with troubles. Where are you, God, when I see no way in front of me.

Now I know God is always with me, He will always make a way. Just that it is me who reluctant to follow his path…

October 22, 2007

發燒時的正確處理

Filed under: Knowledge — jfree @ 2:58 pm

不論大人小孩,發燒是居家護理經常碰到的狀況,但一般人的作法卻有很多錯誤。


最常見的一種錯誤是「蓋好幾條被子悶出一身汗,燒就退了」,因為如此一來,人體皮膚的散熱功能,將無法發揮,使退燒效果大打折扣。因此,除了在剛開始發燒,病人有畏寒感覺時,必須注重保暖﹝但也不需要悶出汗)外,當病人體溫持續偏高時,反而應該解開衣物,以利皮膚散熱。


另一個錯誤觀念是,發燒的人已經生病了,所以不能吹冷氣或吹電扇,必須待在密不通風的溫暖環境。其實,適當的降低室內溫度及加強空氣循環,病人的體溫反而能降得比較快,因此開冷氣或電風扇是需要的,只要避免對著病人身體直吹即可。有人會用酒精擦拭發燒者的身體,試圖幫助降溫,但這種做法爭議性很大,目前已經不鼓勵了。原因是酒精擦拭身體,雖然感覺上冰冰涼涼的,其實反而會使周邊血管收縮,不利散熱。


睡冰枕也是大家常用的方法,基本上是有幫助的,但要注意一歲以下的嬰兒不適用。因為嬰兒的體溫調節中樞並不成熟,如果滾燙的皮膚一下子接觸到冰涼的東西,體溫忽然降的太快,並不是很好。

發燒時的正確護理應是如何呢?

專家的建議包括:

1.以溫水擦拭身體或泡個熱水澡,使血管擴張,加速散熱。

2.多喝開水(一般室溫即可),以利血液循環及新陳代謝。

3.打開冷氣或電風扇,降低環境溫度。

4.去除不必要的衣物,以利散熱。

Powered by ScribeFire.

賴床3分鐘可保健康

Filed under: Knowledge — jfree @ 2:54 pm

當今全世界心血管與腦血管疾病的死亡率,為各種疾病的死亡率之首。

不過若是睡覺 醒來之後能夠「閉目養神三分鐘」,就可以大大減低中風的發生率。中風大多發生 於夜晚,而且最危險的時刻是剛醒來的時候,所以睡醒時先養神休息三分鐘再起床,可以預防中風,尤其老年人、高血壓或心臟病患者更該遵行。
                    
人經過一夜睡眠醒來以後,如果立即從臥姿改為坐姿,甚至突然下床走動,那是非常危險的。因為這時候人身上的血液經過一夜未喝水較黏稠,頭腦較昏沉,立即下床很容易跌倒,造成腦溢血或頭顱撞傷。只要做到睡醒「閉目養神三分鐘」就可以避免,可以說是簡單易行,值得推廣。

因此每個上了年紀的人都應該牢記:
睡醒勿立即下床,先養神休息三分鐘,以免有中風的危險。尤其是患有高血壓及心臟病的患者,一覺醒來切勿隨意搖動頭部,先躺在床上休息三分鐘再下床活動。

Powered by ScribeFire.

October 19, 2007

Hackers find new way to attack PCs

Filed under: Tech — jfree @ 5:35 pm

Spam filling your email inbox isn’t the most annoying thing you can get from the internet. Now hackers are getting more sophisticated in their attacks on home and business PCs.

Sunshine Coast Computer club president Peter Daley is concerned at the rising number of computers being hit by “rootkit” viruses.

In the past few weeks, he has seen the number of infected computers increase dramatically.

“I do a lot of computer repairs and trouble-shooting and where one in 10 machines would have rootkit activity before, that number is now between five or eight out of every 10,” he said.

He said running normal anti-virus software was unlikely to detect it.

Mr Daley said rootkits could be inadvertently downloaded through sharing files on the internet.

“If anti-virus (programs) on Internet Explorer are out of date, hackers can exploit the holes in the system,” he said.

“Sharing files on the internet, via things like music-sharing systems, can open your computer to viruses.”

Quoted from thedaily.com.au on 12:12p.m. 19 October 2007

Powered by ScribeFire.

October 11, 2007

Some quick ways you can help the environment today

Filed under: Environment — jfree @ 6:18 pm

In theory, most of us would like to help the environment, preserve the world’s natural beauty, and generally make this planet a better place to live.

In practice, we don’t necessarily have the time or energy to get involved in major projects, join Greenpeace, protest the corporate polluters, or make sweeping lifestyle changes. We want to help, but with all that’s going on in our lives, it gets put on the back burner.

But playing your part to help the environment doesn’t have to be difficult, time-consuming, or sweeping. You can help out in little ways, making gradual changes, baby steps.

Take a shorter shower.

If you take long showers, consider cutting it short by a few minutes. You’ll conserve water, and the electricity needed to heat up the water, lowering your utility bills and reducing your energy consumption at the same time.

Carpool once this week.

Have a friend or family member or co-worker who makes roughly the same commute as you? Try riding together at least once. It save on fuel consumption, cuts your fuel spending, reduces greenhouse emissions, and you can get a good conversation at the same time.

Use a coffee mug instead of disposable.

If you routinely use disposable cups at work or on the road, use a ceramic coffee cup or a travel mug, reducing the amount of trash you throw away.

Inflate your tires.

Many people don’t realize that their tires are under-inflated. Check the recommended pressure for your tires, and fill them up to that pressure. It only takes a few minutes, but it will save you on fuel consumption (a little) and more
importantly, make your tires last longer and reduce the rubber that’s worn off your tires.

Reuse printed paper.

If you have non-sensitive documents that have been printed out, but are no longer needed, try marking the printed side, and using the clean side for non-official printing. In fact, if you can get your office to do this, you’ll save tons of paper a year.

Turn down your water heater.

Most people have
their water heater’s thermostat turned up too high, wasting energy. Turn it down to 130 degrees, saving energy but still hot enough to kill bacteria.

Plant a tree.

It really doesn’t take much time, and over time more trees in your community can make a difference. Do a few every year, and encourage others to do the same.

Lower your thermostats.

If you use heating, get by with less heat and wear warmer clothes. If you use air-conditioning, get by with less cooling and wear cooler clothes.

Avoid fast food.

Instead, eat at home or at a sit-down restaurant. Fast food restaurants are one of the worst polluters of the environment, both in the massive amounts of beef they must raise, in the wasted packaging, and in the energy they use in so many ways. And they’re tremendously unhealthy. (Urmm, I should try avoid eating McD from now)

Clean your filters.

Clean the filters of your air-conditioners once a month to improve energy efficiency. While you’re at it, change your car’s filters as recommended in your manual.

Fill your toilet tank.

Put a plastic bottle or two, filled with water and rocks, in your tank to reduce the amount of water used in each flush.

Unplug appliances.

If you don’t use an appliance several times a day, it’s better to unplug it, as they often use energy even when turned off.

Unload your car.

Remove excess weight from your car (such as stuff that might be in the trunk) to reduce the amount of fuel you use.

Powered by ScribeFire.

October 10, 2007

Something better than MP3 – Ogg Vorbis

Filed under: Tech — jfree @ 10:39 pm

Most Linux users have probably at least heard of Ogg Vorbis, while most Windows users most likely haven’t, unless they are super nerds.

The Ogg Vorbis website sums it up quite nicely…..

“Ogg Vorbis is a new audio compression format. It is roughly comparable to other formats used to store and play digital music, such as MP3, VQF, AAC, and other digital audio formats. It is different from these other formats because it is completely free, open, and unpatented.”

Ok, so now we know that it’s absolutely free. That alone gives us users some advantages. Linux distributions in general have Ogg Vorbis support built in. That means no additional codec installs. That’s good for everyone.

Of course there are other advantages as well. Installing an mp3 codec in linux could be against the law, depending on where you live. Using Ogg Vorbis, you will be worry free and law abiding.

The Ogg Vorbis format will save you hard drive space. If you choose to save your Ogg files at the same quality as your mp3’s, the Ogg files will be smaller. Or, you can use a higher quality than the mp3’s and still use the same amount of space.

If you’re a developer, there’s a very large advantage. You can include sound files in your software and you won’t pay any licensing fees at all. Many game developers (Epic Games and EA Games for example) have realized this and started using Ogg to keep the money in their pocket.

Ogg Vorbis is also streamable via the icecast audio server. So, there is an alternative for websites and for home media servers that also happens to be completely open source.

At this point, you’re probably thinking……… Portable music players don’t play Ogg Vorbis. You’re absolutely right, if you’re talking about the ipod. But, there are actually quite a few players on the market that support Ogg Vorbis. Don’t believe me? Here’s just one of the many links to lists of Ogg players…. http://www.ciao.co.uk/Portable_MP3_Players_5266512_3-ogg_vorbis

Why should we put up with closed source, licensed, audio codecs when there are perfectly usable alternatives? Why don’t we change the world instead of going along with it?

Powered by ScribeFire.

October 9, 2007

Five great Perl programming techniques to make your life fun again

Filed under: Programming — jfree @ 9:32 am

If you’re a programmer, you know the difference between a beginner and a
master is the ability to write succinct code that does a great deal
with very little work. If you can do this, you can easily raise your
productivity and the quality of your work by an order of magnitude.
Much more importantly, you can have a lot more fun writing code. Read
on to learn how.

Imagine writing a program with a tenth the code you currently use,
ending up with ten times the features, getting fewer bugs, improving
performance, and lowering maintenance costs. And imagine taking the
tedious, repetitive work out, leaving you more time for inspiration and
insight. I’ve spent my career doing that in many languages, more and
more effectively with each new language I learn.

I’m going to use Perl to demonstrate some techniques to accomplish
these goals. Perl is both my first language, and the language in which
I’ve most recently gained some proficiency. It lends itself well to
these types of discussions.

Trick 1: map

The map built-in function is one of the most useful tools in your toolkit. map
takes a list and applies a code block to every element, returning the
list. You can think of it as stream processing: you push the list in
one side and get it back on the other side with some transformation
applied. Inside the code block, you refer to the current element with
the traditional $_ variable. Here’s a really simple example: uppercase every element in a list.

my @lamps = qw(perl php python);my @uc_lamps = map { uc($_) } @lamps;# Result: PERL PHP PYTHON

I just shoved the list in the right side, and it travelled right to
left until finally it popped out on the left side and got assigned into
@uc_lamps. You can do a lot more with map,
though. In fact, it’s pretty much infinitely powerful when it comes to
transforming lists. It’s really just a glorified loop, but if you think
of it as a transformation from input to output, you can really make
some elegant code with it. Here’s another example — make a key-value
hash out of a URL’s query string:

my $query_string = "a=1&b=2&d=3";my %query_params = map { split(/=/, $_) } split(/&/, $query_string);

Do you see how that works? As before, start at the right. The split function splits the incoming string on the & character, and outputs a list. This list goes into the map
block, which splits each element into key and value. This gets assigned
to the hash. That’s a heck of a lot easier than writing loops, and once
you are familiar with it, much easier to read, too. (Note: I’m glossing
over some fine points, such as url-decoding, but this is just an
example)

Trick 2: implement defaults with ||=

One of the most annoying and tedious things you have to do as a
programmer is check your inputs. Let’s just say you’re doing really
basic checking to make sure you even have the input you’re
expecting, and if you don’t, you’re going to fill it in with defaults.
How do you do this? In most languages, you do it with the equivalent of
this Perl code:

sub some_func {   my ( $a, $b, $c ) = @_;   if ( !$a ) {      $a = 5;   }   # Real code here}

Any experienced programmer knows these one-line if
statements tend to take up a lot of code. In fact, they are veritable
screen hogs, with a lower substance-to-lines ratio than most other
programming constructs. Your screen fills with code that does nothing
much functional, leaving you less space to see the real code, and less
brain-power to think about it too. What can you do to fix this?

In Perl, you can use the ||= operator. Its precedence
rules are such that it’ll only do an assignment if the value is false
(’false’ generally means zero, undefined, or the empty string):

   $a ||= 5;

“But wait just a dang minute!” you say. There are a bunch of other ways to do this, such as these:

$a = $a || 5;$a = 5 unless $a;

(Rhetorical question: how many other languages even have these alternatives?)

So what’s so great about the ||= stuff, if there are so many other good ways to do things? Well, I’ve only shown you one place you can put ||= to work. There are a million. Like map, once you start using it, you can’t stop. You can use it for caches, for example:

my %cache;sub expensive_operation {   my ( $key ) = @_;   $cache{$key} ||= get_from_database($key);   return $cache{$key};}

In this example, getting something from the database is really
expensive, so you want to cache it for future calls. The function uses ||=
to check the cache and fetch from the database only if the desired
value isn’t already cached. This is so idiomatic in Perl, it’s actually
called “the Orcish maneuver” (for or cache). But as I said, it’s not the only thing you can do. You can use ||= for sorting on multiple keys, changing light bulbs, and generally achieving world peace.

(Another rhetorical question: why is Visual Basic code so slow to
write, so hard to understand, and so verbose? Hint: think about the
lack of early termination in If statements. ||= is analogous to early termination.)

Trick 3: hash and array slices

Have you ever passed around hashes and arrays and wanted to extract
only certain elements from them? Let’s say you have a subroutine that
accepts a hash reference. Its job is to reverse the query-string
parsing I showed you above. In many languages, you’d have to loop
through the hash’s keys, concatenating the key and value with &, then concatenating these together with =. You can use map() and join() to do this much more simply in Perl, like so:

sub make_query_string {   my ( $vals ) = @_;   return join("&", map { "$_=$vals->{$_}" } keys %$vals);}my %query_params = (   a => 1,   b => 2,   c => 3,   d => 4,);my $query_string = make_query_string(\%query_params);

That’s already a great improvement over looping, especially since
doing it with loops requires keeping track of whether you’re at the
first or the last iteration, so you know whether to insert a separator
between elements. But what happens when you have a hash that has more
keys and values than you want in the query string? This happens a lot.
Coincidentally, my boss and I were pair programming today and needed to do this exact thing (maybe that’s why it’s so fresh in my mind).

The most obvious thing to do is build a new hash with only the keys you want, and send that hash to the subroutine:

my @desired = qw(a c);my %new_params;foreach my $key ( @desired ) {   $new_params{$key} = $query_params{$key};}my $query_string = make_query_string(\%new_params);

Ooooh, that’s ugly. We can at least use map to get rid of the loop while building the new hash:

my %new_params = map { $_ => $query_params{$_} } @desired;

A hash slice is still better, though. It essentially does what that map does, but it’s easier and clearer:

my %new_params;@new_params{@desired} = @query_params{@desired};

I just read a slice of the values from %query_params on the right, and assigned them into another slice with the same keys on the left. Here’s the whole thing, rewritten:

sub make_query_string {   my ( $vals ) = @_;   return join("&", map { "$_=$vals->{$_}" } keys %$vals);}my %query_params = (   a => 1,   b => 2,   c => 3,   d => 4,);my @desired = qw(a c);my %new_params;@new_params{@desired} = @query_params{@desired};my $query_string = make_query_string(\%new_params);

print "$query_string\n";

Though this is a somewhat contrived example in this article, in real
life it’s the furthest thing from contrived. When you write code at a
high level of abstraction, many of your subroutines will just receive a
hash of this and a list of that, and be expected to “do the right
thing” without a lot of fuss. Hash slices make this a lot easier.

Array slices are a related concept. You access a subset of the array
elements as an entire list by simply defining the indexes you want:

my @letters = qw(a b c d e f);my @slice = @letters[1, 4, 3];# @slice is now b, e, d@slice = @letters[0..3, 4];# @slice is now a, b, c, d, f

Trick 4: executable regular expressions

If you’ve programmed in Perl, you’ve used regular expressions.
Perl’s regular expressions are so powerful, Perl really redefined what
it means to process text with a programming language, and regular
expressions in most other languages owe a lot to Perl. But even other
languages that implement Perl-compatible regular expressions may not
implement some of Perl’s features, because in Perl, regular expressions
are an integral part of the language.

One example is the ability to execute the result of a match as code, with the /e
modifier at the end of a substitution. Here’s a real-world example.
Let’s search a MySQL foreign key definition for column names and
reorder them alphabetically, all in place:

my $fk = "FOREIGN KEY (`seq`, `name`) REFERENCES `tbl` (`seq`, `name`)";$fk =~ s#(?<=\()([^\)]+)(?=\))#join(', ', sort(split(/, /, $1)))#ge;# $fk is now "FOREIGN KEY (`name`, `seq`) REFERENCES `tbl` (`name`, `seq`)";

If you want to know how that works, read the comments on my earlier post about a duplicate index and foreign key checker for MySQL.

If you’re like me five years ago, you might think that’s scary as
hell at first. “Execute arbitrary text as though it’s Perl code!?!?
What moron thought up that security exploit waiting to happen and made
it part of the language?!?!?”

Wait a minute, though. Is it really insecure to match some text and
execute it? No, it’s not. In fact, text you’ve matched with a regular
expression is likely to be far better checked, just by the fact that
you’ve specified what it has to look like, than most other input to
your program. This is much more true than you think. In fact, one of
the very safest ways to check any input to your program is by
pattern matching. This is such a powerful way to validate input, it’s
the main way to untaint data when you’re running in taint mode. This is
from the perlsec man page:

Values
may be untainted by using them as keys in a hash; otherwise the only
way to bypass the tainting mechanism is by referencing subpatterns from
a regular expression match. Perl presumes that if you reference a
substring using $1, $2, etc., that you knew what you were doing when
you wrote the pattern.

I won’t go any further into why it’s inherently safe to use the
executable-regular-expression feature, but if you’re not convinced,
talk to an experienced programmer about it. I do want to convince you this is incredibly powerful. My example above implements this pseudo-code:

search text for a string of column namesfor each string,   split it around the delimiters   sort it   join it back together around the delimiters   substitute it back into the original stringdone

You can write any valid Perl code on the right-hand side. Probably
the clearest thing to do is just call a subroutine with the captured
text, and do the work there, instead of inlining it all. Here’s my
example rewritten with a subroutine, and reformatted with the /x modifier:

sub split_sort_join {   my ($text) = @_;   return join( ', ', sort( split( /, /, $text ) ) );}$fk =~ s/        (?<=\()               # Find an opening paren        ([^\)]+)              # Find everything inside parens        (?=\))                # Find a closing paren        /split_sort_join($1)  # Call split_sort_join on the match        /gex;

You can imagine how useful this is if your desired substition is not
hard-coded into the right-hand-side of the substitution, too. For
example, you could pass a callback function to a subroutine, and use
that instead:

sub process_column_names {   my ( $fk, $callback ) = @_;   $fk =~ s/           (?<=\()           # Find an opening paren           ([^\)]+)          # Find everything inside parens           (?=\))            # Find a closing paren           /$callback->($1)  # Call $callback on the match           /gex;   return $fk;}

print process_column_names(   "FOREIGN KEY (`seq`, `name`) REFERENCES `tbl` (`seq`, `name`)",   \&split_sort_join), "\n";

If you’re not a Perl wizard, your head is probably spinning at this
point, so I’ll ease off, even though I’m thinking of several other
things I want to write about this. Here’s the take-away: it’s safe.
It’s powerful. Use it. Once you learn it, you’ll be a much more capable
programmer.

Trick 5: dispatch tables of coderefs

Newcomers to Perl often wonder where the switch statement is. If you really, really want to write something that looks like a case or switch block, you’re a lost soul, but okay, man perlfaq7.
And before you go there, since I know you’re a lost soul, I’ll give you
this ticket to get a slightly cooler room in you-know-where: basically
anything you’ll ever want to do is explained in the Perl manual pages.
Start with man perlfaq and go from there. Even if I can’t convert you away from switch, perhaps I’ve made a difference by pointing you towards these man pages. Fare thee well! I hardly knew ye, gentle reader…

If you’re still reading, you’re one of the ones walking the narrow
path that leads to victory. Good! Let’s talk about how to execute some
code branch depending on the value of a variable. My favorite technique
for this is to use a dispatch table of coderefs — references to
subroutines. This is a succinct way to dispatch execution to somewhere
or other in your program, without the mess and tedious coding you get
with switch statements. Believe me, if you’ve ever tried to maintain someone else’s switch of any size, you’re going to appreciate this.

Let’s say we have a hypothetical interactive program that waits for you to press a key and then does some function.

Okay, I lied. It’s not hypothetical. I use this technique extensively in innotop.
Innotop has many dozens of key mappings, and they are mapped to
different things depending on what mode you’re in. “You pressed c? Oh wait, let me scroll through my big honkin’ switch statement and see what that does… hang on, I’m getting there… can’t find it… oh, you were in that mode! No wonder. Well, let me look at the switch statement for that mode, then…”

Can you imagine? There’s no way I’d have added so many features to
innotop if it were this much of a pain to write, debug and understand.
It doesn’t really matter that I wrote it — six months from now, I won’t
have a clue what all that code is doing. But I will be able to figure out what a keypress does, because I used a dispatch table.

What exactly is a dispatch table? It’s a hash of references to
executable code. Let’s make a simple example: a program that has just
two modes, display_a and display_b. Each of these is handled by a subroutine of the same name. Here is a complete program that’ll loop forever until you press 'q':

#!/usr/bin/perl

use strict;use warnings FATAL => 'all';

use Term::ReadKey;

sub display_a {   print "I am in display_a\n";}

sub display_b {   print "I am in display_b\n";}

my $dispatch_for = {   a => \&display_a,   b => \&display_b,   q => sub { ReadMode('normal'); exit(0) },};

while ( 1 ) {   print "Press a key!\n";   ReadMode('cbreak');   my $char = ReadKey(10);   defined $dispatch_for->{$char} && $dispatch_for->{$char}->();}

Innotop has tons of such dispatch tables. They’re so simple to use;
you just look to see if there’s an entry for whatever your input is,
and if so, you call that to do the work. It can be an anonymous
subroutine, such as the anonymous ‘quit’ subroutine in the example, or
it can be a reference to a named subroutine. If you want a ‘default’
entry, you can do that easily, too:

my $dispatch_for = {   a => \&display_a,   b => \&display_b,   q => sub { ReadMode('normal'); exit(0) },   DEFAULT => sub { print "That key does nothing\n"; },};

# Later   my $func = $dispatch_for->{$char} || $dispatch_for->{DEFAULT};   $func->();

This is much, much simpler than writing switch statements, nested if/else/else if statements, or many other common programming constructs.

What am I getting at?

There is something common to all five of the tricks I listed. It’s
somewhat arbitrary that I listed five (I wanted to keep the article
small enough to digest), and it’s a bit arbitrary which five I chose, because I have many more ideas, but can you see the thread running through them?

It’s elimination of repetition.

Whether it’s repetitive typing, or coding constructs that obviously
iterate over something, I’m trying to show you ways to a) avoid writing
the same code over and over b) avoid reading code that does the same
thing over and over.

Why?

Because repetition kills brain cells. When you’re typing nearly the
same loop or copy-pasting nearly the same code, your brain is not
engaged and productive. You had a moment of insight about how to do
something. In a flash, you saw the way to the end product. Now you have
to write the code to implement it. Let’s just pretend that takes an
hour (on a good day), and you follow it with another insight, and so
on, and so on. You only had eight interested, stimulated, excited
moments in the whole work day? Shoot yourself now and get it over with!

By the same token, when you’re reading code, you have to follow the
program’s logic to understand it. When most programmers study a for
loop, I’d bet money they mentally “execute the loop,” starting at the
beginning and ending at the end, to understand the start, middle and
end of the loop. Every careful coder I’ve known does this, at least
sometimes, because it’s how you understand what the computer is doing.
Mentally executing loops is incredibly draining. It’s just as bad as
typing loops!

The reality is probably even worse, because you’re doing both at the
same time. As soon as you type a loop, you’re immediately reading it.
Reading it. Reading it. As soon as you type — Reading it. As — Reading
it. As soon as you — as soon as you type — type — Reading it.

I’m not making this up. Studies show this is how people read any
type of written material, on screen or off. In fact, one of the most
important and difficult techniques to master in speed reading is to
stop re-reading things you’ve just read. I’m doing it right now as I
write this, backtracking and editing my writing (sometimes I type with
my eyes closed so I can escape this trap more easily).

The combination of writing and reading iterative code is tedious and
boring, and if you’re like me, you have a curious and lively mind, and
you hate “tedious and boring.” That’s why I love writing code that
doesn’t force me to circle like a tiger pacing a cage.

There’s another common thread to everything I wrote, too.

I’m showing you ways to code in a more declarative style.

This is subtle, but after you code in this style for a little while,
you’ll come to understand it: it’s not a procedural programming style.
It’s declarative, where you say what to do instead of how.
It feels much more like writing a specification of the program’s
desired behavior, instead of writing how to accomplish that behavior.
And when you go back to the code later and read it, or maintain someone
else’s code, you appreciate that even more. The program really does
become a spec instead of just an implementation. It’s not that obvious
at first, or with small programs, but take my word for it, it’s true.

Back to that moment of insight: what if, at the point of
inspiration, you could just say “okay computer, do what I want, and you
figure out how to do it.” That’s declarative. Really, once
you had the inspiration that showed you the way to solve the problem,
you didn’t need to write down the code, did you? You understood
everything in that moment, and the rest was just tedium. Writing
declaratively helps you get through the tedium that much faster.

  • The map function is declarative because you specify a transformation and let Perl map it onto each element of a list.
  • Hash and array slices are declarative because you specify what elements you want to read or assign, and let Perl figure out how.
  • ||= is declarative because you let Perl figure out whether the value exists, and whether to fetch a new one if it doesn’t.
  • Executable
    regular expressions are declarative because you just write a
    specification (pattern) of what you want to transform, and provide the
    transformation, and let Perl figure out how to do it.
  • Dispatch
    tables are declarative because you specify a mapping between some input
    and some code, and let Perl do the lookup and dispatch.

You can apply these techniques, one way or another, to any programming language. Another great example is the Behaviour JavaScript library, and the techniques it encourages. Or my own JavaScript date formatting and parsing library, which are not only clearer and simpler to use than their alternatives, but much more powerful and waaaay more efficient.

Powered by ScribeFire.

Next Page »

Blog at WordPress.com.