I added an ascii column to your solution... now it's about twice the size ;=
=2D)

i =3D 0
$<.read.scan(/.{0,16}/m) {
     puts(("%08x " % i) + $&.unpack('H4'*8).join(' ') + ' ['+
       $&.split(//).collect { |c| c.inspect[1] =3D=3D 92 ? '.' :c }.join + =
']' )
     i +=3D 16
}

On Sunday 27 July 2008 22:51:04 Mikael H=F8ilund wrote:
> Oh hi, I just thought I'd golf a solution. I'm sure other people can
> do a much better job than I making a full hexdumping suite, so I just
> had some fun. Can't seem to get it lower than 78 characters,
> unfortunately.
>
> i=3D0;$<.read.scan(/.{0,16}/m){puts"%08x "%i+$&.unpack('H4'*8).join('
> ');i+=3D16}
>
> Expanded and parenthesified, clarified:
>
> i =3D 0
> ARGF.read.scan(/.{0,16}/m) {
> 	puts(("%08x " % i) + $&.unpack('H4'*8).join(' '))
> 	i +=3D 16
> }
>
> ARGF (aliased as $<) is the file handle of all file names given in the
> arguments concatenated, STDIN if none =97 exactly what we need. The
> regex to scan matches between 0 and 16 characters (including newline)
> greedily. Change it to 1,16 if you don't want the empty line at the end.
>
> Instead of letting the block to scan take an argument, I used a trick
> I picked up from the last Ruby Quiz I participated in (Obfuscated
> Email), and use $& inside the block, which is the last regex match.
> Saves two characters \o/
>
> The unpack returns an array of eight strings, each of four characters,
> with the hexadecimal representation of the ASCII value of two
> consecutive characters. Fun, fun, fun.