Read-only files are only protecting the data from being changed, and
that a file and a filename are different.

   file readable               may examine file contents
   file writable               may alter file contents
   file executable             may run file contents

   directory readable          may examine directory contents (list filenames
                                   in directory)
   directory writable          may alter directory contents (remove or
                                   rename filenames)
   direcory executable         may use directory as component in
                                   pathnames, or chdir to that directory

Permissions are on files, not filenames.  Control of filenames is left up
to the directory.  Directories contain filenames (not files!), that
themselves refer to files.

Look at this.  Assume you are the owner of all files and directories
listed, and that your umask (creation mask) is 022.

   directory           filename        file inode          perms
   ----------          ---------       -----------         ------
   alpha               .               100                 0755
   alpha               foo             101                 0644
   alpha               bar             102                 0444

   beta                .               200                 0555
   beta                foo             201                 0644
   beta                bar             102                 0444

Consider two directories, alpha and beta, each of which have the same
two filenames, foo and bar.  alpha/foo is really file #101, but beta/foo
is really file #201 -- different files.  However, the two bar filenames
both refer to the same file, because both #102.  It's just two links
(filenames) to the same file.

The unlink() (remove filename) call does not delete a file -- it deletes
a filename.  When you link() a file into a directory, or creat() a new
file there, it is the directory's permissions that matter.  Likewise,
a rename() is not changing a file -- it's changing its name.

Now, since the ability to modify something is controlled by the
write-permission bit, and THE THING YOU ARE MODIFYING WHEN RENAME A
FILE(NAME) IS A DIRECTORY, all you look at to rename or remove a filename
is the permission of THE DIRECTORY, because it is the DIRECTORY that
you are modifying, not the file.  rename does not

So what happens?  Consider this

   perl -i.bak -pe 1 alpha/foo

Perl wants to do this

   rename alpha/foo to alpha/foo.bak
   create a new alpha/foo

Now, alpha/foo is permission 0644, which means you can write it, *BUT
THIS IS IRRELEVANT*.  You are not altering the file.  You moved it out
of the way and created a new one.  Moving and creating are governed by
the directory's permissions.  Since alpha is mode 0755, this is allowed,
now giving us the following:

   directory           filename        file inode          perms
   ----------          ---------       -----------         ------
   alpha               .               100                 0755
   alpha               foo             101                 0644
   alpha               foo.bak         301                 0644
   alpha               bar             102                 0444

   beta                .               200                 0555
   beta                foo             201                 0644
   beta                bar             102                 0444

What happens when you try to do this?

   perl -i.bak -pe 1 alpha/bar

Well, you seem to think you shouldn't be able to rename it because
it's mode 0555, readonly.  But that's irrelevant.  It's the diretory
that matters.  So it succeeds.  Afterwards, we have this setup:

   directory           filename        file inode          perms
   ----------          ---------       -----------         ------
   alpha               .               100                 0755
   alpha               foo             101                 0644
   alpha               foo.bak         301                 0644
   alpha               bar             302                 0644
   alpha               bar.bak         102                 0444

   beta                .               200                 0555
   beta                foo             201                 0644
   beta                bar             102                 0444

Notice that inode 102, alpha/bar.bak and beta/bar, have never
been touched.  We haven't modified the contents of the file.  We can't.
It's read only.

What happens when you do this:

   perl -i.bak -pe 1 beta/foo

The answer is that you get permission denied.  Ah, you say, this is a bug:
the file (inode 201) is mode 0644, so I should be able to write it.  And
you *CAN* write it.  If you opened it for writing (clobber), or appending,
or update (read/write, no clobber), you would have succeeded.  But you
didn't try to do that.  You tried to do this:

   rename beta/foo to beta/foo.bak
   create a new beta/foo

But you can't do that, because to rename a file, or to create or unlink a file
in a dirctory, you must be able to modify the directory.  But beta is
itself mode 0555, so you don't have permissions to alter it.  So you lose.

Likewise, if you try

   perl -i.bak -pe 1 beta/bar

You lose, but it is not because beta/bar (currently pointing to file number
102, which is the same file that is pointed to by filename alpha/bar.bak)
is readonly.  That fact is irrelevant to this case.  You may not run that
command because you cannot rename the file to beta/bar.bak, which is
illegal due to the readonly *DIRECTORY*.

On the other hand, beta/bar will also stop you from changing the file
itself, because unlike beta/foo, which is mode 0644, beta/bar is mode 0444
and may not be altered.

In short, going back to the original situation

   directory           filename        file inode          perms
   ----------          ---------       -----------         ------
   alpha               .               100                 0755
   alpha               foo             101                 0644
   alpha               bar             102                 0444

   beta                .               200                 0555
   beta                foo             201                 0644
   beta                bar             102                 0444

The file indicated by alpha/foo, inode #101, may be changed due
   to its permissions of 0644, and that filename may be renamed
   and unlinked due to its directory's permissions of 0755.

The file indicated by alpha/bar, inode #102, may *NOT* be changed due
   to its permissions of 0444, but that filename may be renamed
   and unlinked due to its directory's permissions of 0755.

The file indicated by beta/foo, inode #201, may be changed due
   to its permissions of 0644, but that filename may be *NOT* renamed
   or unlinked due to its directory's permissions of 0555.

The file indicated by beta/bar, inode #102, may *NOT* be changed due
   to its permissions of 0444, and that filename may be neither renamed
   nor unlinked due to its directory's permissions of 0555.