Nice :) It is readable indeed, but it could even be better. This is just a small tip, I do not want to offend you in any way, but I think
# warn the user of the wrong input and return
# false, leaving the calling routine dealing
# with things
(defined($coin) && $coin == 25) || (warn("You must insert 25 cents"),
+return 0);
is better written as
# warn the user of the wrong input and return
# false, leaving the calling routine dealing
# with things
(defined($coin) && $coin == 25) || return do {warn("You must insert 25
+ cents"); 0};
IMHO, that would even be more readable
"2b"||!"2b";$$_="the question"