TypeError: no implicit conversion of Symbol into String

Ошибка "no implicit conversion of Symbol into String" появилась при оптимизации рабочего кода и вылезла в этом куске:

{ # 'string of file path':  'string of ruby code'
'/etc/sysconfig/network':   'file_content.gsub!(/^HOSTNAME=.*/, "HOSTNAME=#{my_site}")',
'/etc/hostname':            'my_site',
"#{node['my']['sh']}":      'file_content.gsub!(/^sudo hostname.*/, "sudo hostname #{my_site}")'
}.each do |file_path,code_string|
    Chef::Log.info("#{file_path} File.exist? = #{ File.exist?(file_path) }")

    if File.exist?(file_path)
        file_content = File.read(file_path)
        
        file file_path do
            content eval code_string # eval code_string = run code in code_string
        end
    end
end

В логах Chef ругался на строчку, выделенную жирным, но речь шла конкретно об использовании переменной итератора file_path. После поиска аналогичных пострадавших в сети, подозрение пало на особенность реализации хэша в Ruby, без прямого ответа "а почему". Однако найден был костылик, как вопрос решить, чем и хочу поделиться. Добавление явного преобразования в строку с помощью метода to_s благополучно решило проблему:

Код:

{ # 'string of file path':  'string of ruby code'
'/etc/sysconfig/network':   'file_content.gsub!(/^HOSTNAME=.*/, "HOSTNAME=#{my_site}")',
'/etc/hostname':            'my_site',
"#{node['my']['sh']}":      'file_content.gsub!(/^sudo hostname.*/, "sudo hostname #{my_site}")'
}.each do |file_path_cur,code_string|
    file_path = file_path_cur.to_s # without to_s ---> TypeError: no implicit conversion of Symbol into String
    Chef::Log.info("#{file_path} File.exist? = #{ File.exist?(file_path) }")

    if File.exist?(file_path)
        file_content = File.read(file_path)
        
        file file_path do
            content eval code_string # eval code_string = run code in code_string
        end
    end
end

Если вам помогла или просто понравилась статья - плюсаните/поделитесь, пожалуйста.

Добавить комментарий