in reply to word boundary match problem

I'm surprised this works at all - it certainly isn't doing what you think it is. The :

while(<@source>) { ... }
is actually doing a glob based on the contents of the file and is making $_ the actual line where (not unexpectedly) there isn't a match.

I think you meant:

foreach ( @source ) { ... }
or
while(<SOURCE>) { ... }
if the latter you will need to move the close to after the loop.

/J\