to_yaml raises a NoMethodError when used with a SimpleDelegator #100

aisrael opened this Issue Nov 14, 2012 · 9 comments


None yet

7 participants

aisrael commented Nov 14, 2012

The following code:

require 'delegate'
require 'yaml'

class Foo

class Delegate < SimpleDelegator

class Bar < :foo

foo =
delegate =
bar =

bar.to_yaml # raises NoMethodError: undefined method `name' for nil:NilClass

The last line raises an error:

`block in initialize': undefined method `name' for nil:NilClass (NoMethodError)

I've looked at the source for yaml_tree.rb around line 26 and it goes:

@dispatch_cache = do |h,klass|
    method = "visit_#{( || '').split('::').join('_')}"

Is this an edge-case interaction between SimpleDelegator and Psych YAML engine? Neither foo.to_yaml nor delegate.to_yaml work properly—it seems that only when another object contains a reference to a SimpleDelegator does to_yaml fail.

sbounmy commented Nov 25, 2012

having the exact same issue with delayed_job_active_record by using handle_asynchronously to queue jobs


A hackish workaround:

# note the resulting encoding is a bit ugly
class Delegator
  def encode_with coder
    ivars = instance_variables.reject {|var| /\A@delegate_/ =~ var}
    coder['obj'] = __getobj__
    unless ivars.empty?
      coder['ivars'] = Hash[{|var| [var[1..-1], instance_variable_get(var)]}]

  def init_with coder
    (coder['ivars'] || {}).each do |k, v|
      instance_variable_set :"@#{k}", v
    __setobj__ coder['obj']
noma4i commented May 27, 2013

Same error if trying to serialize params received from multipart form submission.

  1. Create sample form with file upload.
  2. make params.to_hash.to_yaml
  3. Enjoy!
ixti commented Jun 14, 2013

Same error when you try to dump response from HTTParty:

require 'httparty'
require 'yaml'

module FQL
  include HTTParty

  base_uri ''

  def self.link_stat url
    self.get("/fql", {
      :query => {
        :q => <<-FBQL.squeeze(' ').strip
          select total_count
            from link_stat
           where url=#{url.inspect}

YAML.dump FQL.link_stat ""
afn commented Sep 11, 2014

Maybe psych should define visit_BasicObject in addition to (or instead of) visit_Object? It blows up here:

        @dispatch_cache = do |h,klass|
          method = "visit_#{( || '').split('::').join('_')}"

          method = respond_to?(method) ? method : h[klass.superclass]

          raise(TypeError, "Can't dump #{target.class}") unless method

          h[klass] = method

because it traverses up the class hierarchy expecting to encounter a class for which method is defined, but there is no catch-all for objects that don't inherit from Object.

@afn afn referenced this issue in collectiveidea/delayed_job Sep 12, 2014

undefined method `name' for nil:NilClass with rails 4.2 beta #687


Defining a serialization mechanism for BasicObject doesn't make sense for solving a problem with a DelegateObject. We can add a custom serialization mechanism for SimpleDelegator, I think.

afn commented Sep 15, 2014

@tenderlove I agree; these are probably two separate problems: (1) can't serialize SimpleDelegator-based objects, and (2) can't serialize objects that derive from BasicObject.

For the latter, there are a couple of reasonable approaches:

  1. Raise an error with a more sensible message than undefined method `name' for nil:NilClass
  2. Define a default fallback serializer for BasicObject.

Well, Marshal seems to be able to dump SimpleDelegator based objects, so I think Psych should support it. Marshal won't dump BasicObjects though.

@tenderlove tenderlove closed this in #205 Sep 17, 2014
ixti commented Sep 18, 2014

👍 👏 ❤️

@handlers handlers added a commit to sunlightlabs/opencongress that referenced this issue Feb 11, 2015
@handlers handlers Specify psych version to make serialization work a504b7f
@myfreeweb myfreeweb added a commit to myfreeweb/freshcerts that referenced this issue Feb 11, 2016
@myfreeweb myfreeweb update deps, add psych dep
ruby has built-in psych but it's old on some rubies
and it has this issue there: ruby/psych#100
@myfreeweb myfreeweb referenced this issue in myfreeweb/freshcerts Feb 11, 2016

OpenSSL::X509::RequestError - header too long #1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment