my $buf = make_buf(3); &$buf('hi'); &$buf('moo'); print join(' ', &$buf) . "\n"; # 'hi moo' $buf->('foo','no'); print join(' ', $buf->()) . "\n"; # 'moo foo no' sub make_buf { my $size = shift || 3; my @buf; my $pos = -1; my $last = $size - 1; return sub { if (@_) { while (@_) { $buf[ $pos==$last ? $pos=0 : ++$pos ] = shift } } elsif (wantarray) { return ($#buf==$last ? @buf[ $pos+1 .. $last, 0 .. $pos ] : @buf); } else { warn "Call with an argument or in list context"; return; } } }