>    str = array.shift.nonnil?.sub(/^XX/, '')
>
>のように書けたら嬉しいのですが、これは多分文法上不可能なんですよね?

さらに、method_missing を使えばこのように書けますが、この場合
Object で定義されているメソッド(dup など)を使うと意図したように
動かないので(Dummy#dup が呼ばれてしまい、method_missing が呼ばれない)
適宜 undef する必要があります。

class Dummy
# undef dup
  def method_missing(*a, &b) # 定義されていないメソッドが呼ばれると、ここに来る
    nil
  end
end

class Object
  def nonnil?
    nil? || self == "" ? Dummy.new : self
  end
end

for line in ["1\t2\t3", "1.0\t2\t", "1\t2\tXXfoo"]
  array = line.chomp.split("\t")
  float = array.shift.nonnil?.to_f
  int   = array.shift.nonnil?.to_i
  str   = array.shift.nonnil?.sub(/^XX/, '')
# str   = array.shift.nonnil?.sub(/^XX/) { '' }
  xxx   = array.shift.nonnil?.dup
  p [float, int, str, xxx]
end

/////////////////////////

E:\>ruby d.rb
[1.0, 2, "3", #<Dummy:0x2b5bb3c>]
[1.0, 2, nil, #<Dummy:0x2b5b914>]
[1.0, 2, "foo", #<Dummy:0x2b5b68c>]

undef dup のコメントを外すと

E:\>ruby d.rb
[1.0, 2, "3", nil]
[1.0, 2, nil, nil]
[1.0, 2, "foo", nil]