It's not ruby, it's your shell.
Many shells expand the ? character to match a single character in command line arguments.
It's useful, if you have a bunch of files name tempA,temp1,tempB,...,temp9 that you want to delete, but you don't want to delete 'temple'
% rm temp?
So I'm guessing you have a file or directory in your working directory named 'z', and the ? matches that, so it gets replaced by the shell.
Normally, when inside single quotes (like your ruby script) it wouldn't get expanded, but since you're passing the question mark to a shell command, it gets expanded there.
% ruby -e 'puts %x[ echo ? ]'
z
%
Should show you the same behaviour.
Also, if you touch a couple other single character filenames like a b c d, those should show up too:
% touch a b c
% ruby -e 'puts %x[ echo ? ]'
a b c z
%
If you want to avoid this when calling exterior shell commands from within ruby, you'll have to escape any strings you pass out. For most purposes String#inspect
should give a good enough escaping.