views:

140

answers:

2

Until now, the project I work in used ASCII only in the source code. Due to several upcoming changes in I18N area and also because we need some Unicode strings in our tests, we are thinking about biting the bullet and move the source code to UTF-8, while using the utf8 pragma (use utf8;)

Since the code is in ASCII now, I don't expect to have any troubles with the code itself. However, I'm not quite aware of any side effects we might be getting, while I think it's quite probable that I will get some, considering our environment (perl5.8.8, Apache2, mod_perl, MSSQL Server with FreeTDS driver).

If you have done such migrations in the past: what problems can I expect? How can I manage them?

+10  A: 

The utf8 pragma merely tells Perl that your source code is UTF-8 encoded. If you have only used ASCII in your source, you won't have any problems with Perl understanding the source code. You might want to make a branch in your source control just to be safe. :)

If you need to deal with UTF-8 data from files, or write UTF-8 to files, you'll need to set the encodings on your filehandles and encode your data as external bits expect it. See, for instance, With a utf8-encoded Perl script, can it open a filename encoded as GB2312?.

Check out the Perl documentation that tells you about Unicode:

Also see Juerd's Perl Unicode Advice.

brian d foy
+3  A: 

A few years ago I moved our in-house mod_perl platform (~35k LOC) to UTF-8. Here are the things which we had to consider/change:

  • despite the perl doc advice of 'only where necessary', go for using 'use utf8;' in every source file - it gives you consistency.
  • convert your database to UTF-8 and ensure your DB config sets the connection charset to UTF-8 (in MySQL, watch out for field length issues with VARCHARs when doing this)
  • use a recent version of DBI - older versions don't correctly set the utf8 flag on returned scalars
  • use the Encode module, avoid using perl's built in utf8 functions unless you know exactly what data you're dealing with
  • when reading UTF-8 files, specify the layer - open($fh,"<:utf8",$filename)
  • on a RedHat-style OS (even 2008 releases) the included libraries won't like reading XML files stored in utf8 scalars - upgrade perl or just use the :raw layer
  • in older perls (even 5.8.x versions) some older string functions can be unpredictable - eg. $b=substr(lc($utf8string),0,2048) fails randomly but $a=lc($utf8string);$b=substr($a,0,2048) works!
  • remember to convert your input - eg. in a web app, incoming form data may need decoding
  • ensure all dev staff know which way around the terms encode/decode are - a 'utf8 string' in perl is in /de/-coded form, a raw byte string containg utf8 data is /en/-coded
  • handle your URLs properly - /en/-code a utf8 string into bytes and then do the %xx encoding to produce the ASCII form of the URL, and /de/-code it when reading it from mod_perl (eg. $uri=utf_decode($r->uri()))
  • one more for web apps, remember the charset in the HTTP header overrides the charset specified with <meta>
  • I'm sure this one goes without saying - if you do any byte operations (eg. packet data, bitwise operations, even an MIME Content-Length header) make sure you're calculating with bytes and not chars
  • make sure your developers know how to ensure their text editors are set to UTF-8 even if there's no BOM on a given file
  • remember to ensure your revision control system (for google's benefit - subversion/svn) will correctly handle the files
  • where possible, stick to ASCII for filenames and variable names - this avoids portability issues when moving code around or using different dev tools

One more - this is the golden rule - don't just hack til it works, make sure you fully understand what's happening in a given en/decoding situation!

I'm sure you already had most of these sorted out but hopefully all that helps someone out there avoid the many hours debugging which we went through.

John O'Rourke