2017-01-11 1 views
2

Rails 3.2.22.2アプリケーション用のRuby 2.3.3へのアップグレードをテストし、 Tempfile.newの最初の引数として、それはハッシュとして終わります。Ruby 2.3.3:奇妙なTempfile.new([name、prefix])ベース名をハッシュに変換

私はbasename引数が渡されている出力にtempfile.rbをパッチしました

irbセッション(非Railsの)で、すべてが正常である:。rails consoleセッションで

> require 'tempfile' 
true 
> Tempfile.new(['test', '.csv']) 
["home", ".csv"] # output of basename argument for Tempfile.new 
=> #<Tempfile:/var/blah/test###.csv> 

> 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' 

宝石や何かになりたいのですが、なぜこのようなことが起こっているのか、私の人生を理解することはできません。どこで、何が行動を変えているのか。

デバッグ方法に関するご意見やご提案はありますか?

+1

パッチを当てたtempfile.rbの中に 'puts caller'の出力はありますか? –

答えて

2

あなたの場合、コードのどこかにArray#to_hashメソッドが定義されていると思います。

メソッドにデフォルトのパラメータ(この場合は)と二重スプラットパラメータがある何らかの理由で、Rubyは最初のパラメータでto_hash関数を呼び出します。

は、次の例を参照してください:

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"]) 

この意志出力

to_hash called on ["Joe", "Bloe"] 
val = ["Joe", "Bloe"] 

しかしvalのparamにはデフォルト値はありませんとき、あなたが買ってあげる:

val = ["Joe", "Bloe"] 

注意をTempFile#initialize関数のシグネチャがRuby 2.1からRuby 2.2に変更されました。

ここでdiffがあります:basenameはもうデフォルト値を持っていないことを

- def initialize(basename, *rest) 
+ def initialize(basename="", tmpdir=nil, mode: 0, **options) 

注意してください。

+0

ありがとうございました。それは本当に素晴らしい発見です!これでしばらくの間苦労している。 – bschaeffer

0

私のコンソールでこれを試したところ、エラーは発生しませんでした。私はこの方法make_tmpnameが前に異なる方法で処理されたと考えているため、いくつかのことを試してみてください、

  1. は、あなたがあなたのレールのアプリでルビー2.3以降を使用していることを確認してください。
  2. .csvの引用符がチルダではなく引用符であることを確認してください。私は、これはあなたのエラーを引き起こしているものを一日の終わりに、役に立てば幸いこのTempfile.new(['test', /re/])

が第二のためにnilを返している。この方法try_convertで行う場合

  • 私はルビー2.3.1を使用して同じエラーを取得しますあなたに渡す引数Tempfile.new

  • +0

    '\' 'はバックティック(または[重アクセント](http://www.fileformat.info/info/unicode/char/0060/index.htm))です。 '〜'はチルダです(http://www.fileformat.info/info/unicode/char/007e/index.htm)。 –

    +0

    私は誰かがそれについて私を修正するだろうが、名前を覚えていないことを知っていた、ありがとう。 –

    +0

    フィードバックいただきありがとうございます。上記のコードは、アプリケーションの '〜'や '\' 'のコードであり、私は2.3.3を使ってエラーを生成しています。正規表現を使って同じエラーが発生すると言うと、あなたは '[]' argsがハッシュに変換されているのを見ていますか? – bschaeffer

    0

    これは私がそれを修正した方法です。

    class Tempfile 
        def initialize(basename="", tmpdir=nil, mode: 0, **options) 
        warn "Tempfile.new doesn't call the given block." if block_given? 
    
        basename = basename.keys if basename.kind_of?(Hash) 
    
        @unlinked = false 
        @mode = mode|File::RDWR|File::CREAT|File::EXCL 
        ::Dir::Tmpname.create(basename, tmpdir, options) do |tmpname, n, opts| 
         opts[:perm] = 0600 
         @tmpfile = File.open(tmpname, @mode, opts) 
         @opts = opts.freeze 
        end 
        ObjectSpace.define_finalizer(self, Remover.new(@tmpfile)) 
    
        super(@tmpfile) 
        end 
    end 
    
    関連する問題