T-mobile customer service finally comes through

masthead_tmobile.gif After a few weeks of pleading with my cell phone carrier, they have finally resolved a billing error. This is a good thing for both of us. Good for me, because I generally like my calling plan and would hate to give it up, and good for them, because they will continue to get my business.

Back in March, we traveled to Italy, Hungary, and Israel for a couple of weeks. Since I have a GSM phone, I called T-mobile from the airport to find out if I could use it overseas.

The customer service rep told me that yes, in fact I could use the phone in Europe and Israel. When I asked about rates, she said that it was basically 29 cents a minute. I asked several follow-up questions — 29 cents a minute from Europe to the US? Yes. How about from Europe to Europe or from Europe to Israel? Yes, same 29 cents a minute rate applies. From Israel to US? Also 29 cents. Same per-minute rate for incoming and outgoing calls? Yes. Any service charge or monthly fee? Nope.

This seemed like a pretty good deal. So sure enough, we used the phone quite a bit to make hotel reservations, reconfirm our flights, and call our friends and family. In total, we made 166 minutes of calls while we were overseas.

When we got back to the US, I got the bill. Instead of the $48 in roaming charges I was expecting, somehow we managed to rack up a total of $313. Simply put, the rates were totally different from what the rep quoted me. I was billed 99 cents a minute for calls made within Italy and Hungary, and $2.99 a minute for calls made within Israel.

So I called T-mobile customer service and explained the situation calmly and patiently to the rep who answered. Laura seemed very friendly and sympathetic, but ultimately was unable to help me. She explained that the other rep must’ve been confused, since the 29 cent rate is for the opposite calling direction.

Laura even put in a request for a $265 credit, but she said wasn’t sure it was going to go through. The fact that the original rep never mentioned the 29 cent rate explicitly in my file meant that the billing folks would likely reject my credit request. I explained that I would be happy to talk to her supervisor or anyone in billing if they wanted more details.

A couple of weeks passed and no contact from T-mobile. The auto-pay thing kicked in and my credit card was charged for the $313 amount. I guess they rejected the $265 credit request.

I called back today and got a hold of another rep. I explained the whole situation to John, and he put me on hold so he could read up on all of the notes in my file to see what happened. When John came back from hold, he apologized for the overbilling problem, but explain that the billing department rejected the claim because there was no evidence in the file that the rep in March said anything about the 29 cent rate.

I told John, “I’m really frustrated because I think T-mobile should honor the rate that I was quoted back in March.” I even explained that I understand now that the actual rates are $0.99 and $2.99 and that the original rep was wrong to quote me 29 cents back in March, but that I feel that I shouldn’t be penalized for her error. He apologized and empathized, but admitted that he was powerless to help me. He offered to put in another credit request for $265, but was pretty sure it would just get rejected again.

I told him that I guess I’m going to need to cancel my account if they can’t honor the rate that they quoted me.

Those must have been the magic words, because John said, “Well, before we go down that road, let me see if I can find someone in a different department to help you.” He put me on hold for a while longer, and Susan got on the phone. She had already read my file, but asked me to explain what happened in my own words. We talked for a while, and she said she needed to talk to her supervisor, so could I please hold.

Susan finally came back from hold with the greeting, “Good news. We’re going to honor the rate you were quoted, so we’re going to credit your account for $265.”

Apparently I found the right person to talk to. Thanks, Susan. You’ve restored my faith in T-mobile.

Ask Yahoo! RSS release

ask1.gif Ask Yahoo!, a daily column that features Q&A with Yahoo!’s expert team of Surfers, is officially syndicating its content via RSS.

As reported here back in April, RSS support for Ask Yahoo! had previously been available as a Beta release only.

This week, Ask Yahoo! marks five wonderful, question-filled years. To celebrate this momentous occasion, we’ve given the site a fresh look and some cool new features. So click around, read up, and ask away!

The Most Popular Questions page is my favorite of the new features.

To subscribe to Ask Yahoo!, click the green XML Sub button: Subscribe to "Ask Yahoo!" with your favorite aggregator.

Ploni ben Ploni

John Doe.

Joe Schmoe.

Ploni ben Ploni.

When the Gemara needs a placeholder name but doesn’t want to use a real one, apparently it uses the name פלוני (transliterated here as Ploni). Ploni can be used both as a person’s name as well as a name of a place.

In mock contracts, sometimes the formula פלוני בן פלוני במקומ פלוני (Ploni ben Ploni b’Makom Ploni) is used. This translates rougly as “Ploni, son of Ploni, from the city of Ploni.”

Delightful. I remember finding it equally amusing a few years ago when I learned that French programmers don’t name temporary variables foo or bar, but rather toto and tata.


Adventures with DB_File::Lock

I like the Unix DBM file format (a.k.a BerkeleyDB). I use it for static data (like the zip code-to-latitude/longitude database for the Hebcal Interactive Jewish Calendar) and for dynamic data (such as the subscriber database for the Mountain View High School Alumni Internet Directory).

BerkeleyDB is also great because it has many language interfaces. I can access the same DB files in both Perl and PHP.

My high school alumni directory subscriber database has experienced corruption a few times recently. It’s a good thing I also keep a daily text backup of the database in RCS because it makes it easy to rebuild the DB.

But it’s obvious to me that the underlying cause of the problem is concurrent access that isn’t protected by mutual exclusion. Heck, I wrote the code back in 1995 when I didn’t know better.

So I’ve gotta go add some locking code to the 25 scripts that manage the site.

However, older versions of BerkeleyDB (such as the one installed on my ISP) don’t natively support locking, so I’ve gotta use flock for concurrency. No problem; it’s relatively easy to turn every occurance of this:

use DB_File;


tie(%DB, 'DB_File', $file, O_RDWR|O_CREAT, 0644, $DB_HASH);

$DB{'foo'} = 'bar';


into something that looks like this:

use DB_File;

use Fcntl qw(:DEFAULT :flock);


my($db) = tie(%DB, 'DB_File', $file, O_RDWR|O_CREAT, 0644, $DB_HASH);

defined($db) || die "Can't tie $file: $!\n";

my($fd) = $db->fd;

open(DB_FH, "+<&=$fd") || die "dup $!";

unless (flock (DB_FH, LOCK_EX)) { die "flock: $!" }

$DB{'foo'} = 'bar';

flock(DB_FH, LOCK_UN);

undef $db;

undef $fd;



Bingo. Problem seems to be fixed. No more DB corruption.

But then, a few weeks later, I get DB corruption again. Ugh. Turns out that I managed to fix 24 of the scripts, but there’s one that I occasionally run by hand (the one that removes someone from the directory) that I forgot to add locking code to. With flock, it only takes one script to screw it up.

So last night I was about to go through the scripts and update them, but reading the DB_File manpage, they point out a possible problem with the classic “tie the db, dup the fd, then flock” approach. So fixing the 25th script to use the same locking scheme won’t necessarily solve the problem either. Doh!

Reading a little further down the manpage, I see a reference to a simple CPAN module called DB_File::Lock that transparently does flocking when you tie and untie the DB. It’s perfect for what I need.

Now I can simply do a search-and-replace throughout the entire codebase and change all DB_File references to DB_File::Lock, and get rid of whatever dup/flock stuff I used to use.

use DB_File::Lock;


tie(%DB, 'DB_File::Lock', $file, O_RDWR|O_CREAT, 0644, $DB_HASH, 'write');

$DB{'foo'} = 'bar';


I’ve also considered moving the code from DBM files into MySQL. My ISP started offering limited MySQL access for an additional buck a month, and relational DBs tend to solve the concurrent access problem in a much more elegant (and consistent) way.

Unfotunately, it would be too much work. I don’t want to rewrite all of my 8-year-old Perl code that serializes an alumni record (just a bunch of key=value pairs) into a delimited string. And the DB access parts of the code aren’t very well abstracted, so switching from a simple hash DB format to a more structured multi-column format is going to be trickier than it seems.

Someday when I find the time to do a complete rewrite I’ll use MySQL as the backing store. And I’ll use that opportunity to get rid of all of my perl4-isms and replace them with appropriate perl5 constructs. Heck, if I delay long enough, perhaps I can go straight from perl4 to perl6! :-)

For now, DB_File::Lock is good enough.

Mikel Maron: Reactive Links

A superb idea today from Yahoo! alumnus Mikel Maron:

Reactive Links. Anytime someone click-thrus on these redirect links, the service records that action… more active links could be big and red and quiet links could small and blue, or whatever you like. These links change their character depending on their usage. [Brain Off]

It reminds me of a little bit of internal visualization our data mining group did where a modified version of the Yahoo! homepage showed a click-percentage count next to each hyperlink on the page. You could pretty easily see that people were always interested in clicking on certain elements on the page (such as the word “Free”) and that you could also induce users to try different Yahoo! services by occasionally highlighting one of them (by displaying them in bold or with a background color).

Changing the size of the links is another interesting visualization technique, but it can throw off the page layout so much that it becomes distracting and less helpful.

Jerry’s Guide to the World Wide Web

akebono.jpg At lunch today we were talking about trademarks and whether Yahoo! is a brand name or a generic term. Since it’s used in Chapter 1 of Gulliver’s Travels, it clearly pre-dates the web company. And the first use with an exclamation point probably comes from the Erasure song which was released in 1988 on The Innocents album.

We never quite sorted it out, but the discussion morphed into the history of the company. We wondered how many links there are still pointing at akebono.Stanford.Edu.

Now there’s one more. :-)