This is something Ruby likely got form Perl,but they cribbed it wrong. Perl's post-conditionals only work on single statements, not blocks. You can use them for functional style statements though. I.e.
# Not allowed
for ( 1 .. 10 ) {
say $_;
} if 1;
# Allowed
map { say $_ } ( 1 .. 10 ) if 1;
The idea seems to be that a post-conditional should be simple and obvious by the time you've parsed the statement. A block makes it confusing, as does mixing post control structures
Post-loop structures have the same limitation:
# Not allowed
{ say "foo"; say $_ } for ( 1 .. 10 );
# Allowed
say $_ for ( 1 .. 10 );
When used correctly, these can become very succinct and clear.
my %data = get_data_record_hash("foo");
$data{$_} = update_field(data{$_}) for ('field1','field4',other_field');
# Compare to map, which normally you expect to return values
map { $data{$_} = update_field(data{$_}) } ('field1','field4',other_field');
The single statement limitation keeps you from going wild in ways that are probably not useful to future readers of the code (including you).
I'd argue that register_globals is never a good idea. Post-if is sometimes a good idea, with one case that is problematic (less readable, not even a negative affect on function)
really.long.thing.that.i.try.to.parse.in.my.head if acutally_almost_never_happens
which is harder to read since I read top to bottom / left to right, but the flow is bottom to top and right to left