Testing an upgrade to Ruby 2.3.3 for our Rails 3.2.22.2 application, and getting a weird situation where we are passing an array as the first argument to Tempfile.new
, but it's ending up as a hash.
I've patched tempfile.rb
to output the basename
argument being passed in.
In an irb
session (non-Rails), everything is fine:
> require 'tempfile'
true
> Tempfile.new(['test', '.csv'])
["home", ".csv"] # output of basename argument for Tempfile.new
=> #<Tempfile:/var/blah/test###.csv>
In a rails console
session:
> Tempfile.new(['test', '.csv'])
{"test"=>nil, ".csv"=>nil}
ArgumentError: unexpected prefix: {"test"=>nil, ".csv"=>nil}
from /path/to/ruby-2.3.3/lib/ruby/2.3.0/tmpdir.rb:113:in `make_tmpname'
Gotta be a gem or something, but can't figure out for the life of me why this is happening or where or what is changing the behavior.
Any ideas or suggestions on how to debug?
In your case I think that somewhere in your code you have the Array#to_hash
method defined.
I had the same issue and for some reason when a method has a default param, in this case basename=""
, and a double splatted parameter, Ruby calls the to_hash
function on the first param.
See the following example:
class Dummy
def initialize(val = "", **options)
puts "val = #{val}"
# puts "Options: #{options}"
end
end
class Array
def to_hash
puts "to_hash called on #{self}"
end
end
Dummy.new(["Joe", "Bloe"])
This will output
to_hash called on ["Joe", "Bloe"]
val = ["Joe", "Bloe"]
But when there's no default value for the val
param, you'll get:
val = ["Joe", "Bloe"]
Note that the TempFile#initialize
function signature was changed from Ruby 2.1 to Ruby 2.2.
Here's the diff:
- def initialize(basename, *rest)
+ def initialize(basename="", tmpdir=nil, mode: 0, **options)
Notice that basename
doesn't have a default value anymore.