Bryan Glazer
Bryan Glazer

Reputation: 852

Deserializing ruby object from YAML failure: allocator undefined for Method (TypeError)

I'm trying to save the current state of a game. I serialize the game_state object to YAML by making a new file and writing YAML::dump(game_state). I then use this code to deserialize it:

input = YAML.open(@text_input.to_s + '.yml', 'r')
playstate = YAML.load(input.read)
puts playstate

I get this error at runtime

C:/Ruby192/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:227:in `allocate': allocator
undefined for Method (TypeError)
        from C:/Ruby192/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:227:in `revive'
        from C:/Ruby192/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:183:in `visit_Psych_Nodes_Mapping'
        from C:/Ruby192/lib/ruby/1.9.1/psych/visitors/visitor.rb:7:in `accept'
.......
(I can post the whole trace if necessary)

So, is my YAML poorly formatted? This is my first experience with it, so the stack trace didn't really mean much to me. Any help is appreciated.

This is what my YAML file looks like for the game_state.

--- &20832876 !ruby/object:PlanetDefense::PlayState
options:
  :level: 0
  :score: 0
game_objects: !ruby/object:Chingu::GameObjectList
  game_objects: []
  visible_game_objects: []
  unpaused_game_objects: []
input_clients: []
previous_game_state: !ruby/object:PlanetDefense::MenuState
  options:
  - :start
  - :options
  - :credits
  - :quit
  game_objects: !ruby/object:Chingu::GameObjectList
    game_objects: []
    visible_game_objects: []
    unpaused_game_objects: []
  input_clients: []
  previous_game_state: !!null 
  current: 0
  selected: !ruby/object:Gosu::Color
    __swigtype__: _p_Gosu__Color
  font: !ruby/object:Gosu::Font
    __swigtype__: _p_Gosu__Font
  background_image: !ruby/object:Gosu::Image
    __swigtype__: _p_Gosu__Image
  title_image: !ruby/object:Gosu::Image
    __swigtype__: _p_Gosu__Image
  input:
    :up_arrow:
    - !ruby/object:Method {}
    :down_arrow:
    - !ruby/object:Method {}
    ! ': ':
    - !ruby/object:Method {}
    :enter:
    - !ruby/object:Method {}
    :return:
    - !ruby/object:Method {}
  music: !ruby/object:Gosu::Song
    __swigtype__: _p_Gosu__Song
  game_state_manager: &22575264 !ruby/object:Chingu::GameStateManager
    inside_state: !!null 
    game_states:
    - *20832876
    - &20827872 !ruby/object:PlanetDefense::RingMenu
      opaque: false
      modal: true
      rotation: 1
      x_radius: 200
      y_radius: 100
      font: !ruby/object:Gosu::Font
        __swigtype__: _p_Gosu__Font
      background_image: !ruby/object:Gosu::Image
        __swigtype__: _p_Gosu__Image
      title_image: !ruby/object:Gosu::Image
        __swigtype__: _p_Gosu__Image
      cx: 512
      cy: 459
      caption: !ruby/object:Chingu::Text
        size: 15
        options:
          :rotation_center: :top_left
          :zorder: 4
        parent: *20832876
        paused: false
        visible: true
        color: !ruby/object:Gosu::Color
          __swigtype__: _p_Gosu__Color
        mode: :default
        x: 512
        y: 459
        zorder: 4
        angle: 0
        factor_y: 2.0
        factor_x: 1.8
        factor: 1
        center_x: 0.5
        center_y: 0.5
        text: SAVE GAME
        font: Helvetica
        line_spacing: 1
        align: :left
        max_width: !!null 
        padding: 5
        gosu_font: &20826948 !ruby/object:Gosu::Font
          __swigtype__: _p_Gosu__Font
          name: Arial
        image: !ruby/object:Gosu::Image
          __swigtype__: _p_Gosu__Image
        height: 20
      items:
      - !ruby/object:PlanetDefense::RingMenu::Icon
        options:
          :scale: 2
          :zorder: 10
          :image: &20827932 !ruby/object:Gosu::Image
            __swigtype__: _p_Gosu__Image
          :center: 0.5
        parent: *20832876
        paused: false
        visible: true
        image: *20827932
        color: !ruby/object:Gosu::Color
          __swigtype__: _p_Gosu__Color
        mode: :default
        x: 512.0
        y: 359.0
        zorder: 10
        angle: 0.0
        factor_y: 2
        factor_x: 2
        factor: 2
        center_x: 0.5
        center_y: 0.5
        title: SAVE GAME
        action: !ruby/object:Proc {}
      - !ruby/object:PlanetDefense::RingMenu::Icon
        options:
          :scale: 2
          :zorder: 10
          :image: &20828040 !ruby/object:Gosu::Image
            __swigtype__: _p_Gosu__Image
          :center: 0.5
        parent: *20832876
        paused: false
        visible: true
        image: *20828040
        color: !ruby/object:Gosu::Color
          __swigtype__: _p_Gosu__Color
        mode: :default
        x: 321.78869674096927
        y: 428.09830056250524
        zorder: 10
        angle: 288.0
        factor_y: 2
        factor_x: 2
        factor: 2
        center_x: 0.5
        center_y: 0.5
        title: QUIT TO MENU
        action: !ruby/object:Proc {}
      - !ruby/object:PlanetDefense::RingMenu::Icon
        options:
          :scale: 2
          :zorder: 10
          :image: &20827956 !ruby/object:Gosu::Image
            __swigtype__: _p_Gosu__Image
          :center: 0.5
        parent: *20832876
        paused: false
        visible: true
        image: *20827956
        color: !ruby/object:Gosu::Color
          __swigtype__: _p_Gosu__Color
        mode: :default
        x: 394.44294954150536
        y: 539.9016994374947
        zorder: 10
        angle: 216.0
        factor_y: 2
        factor_x: 2
        factor: 2
        center_x: 0.5
        center_y: 0.5
        title: RETURN TO GAME
        action: !ruby/object:Proc {}
      - !ruby/object:PlanetDefense::RingMenu::Icon
        options:
          :scale: 2
          :zorder: 10
          :image: &20828004 !ruby/object:Gosu::Image
            __swigtype__: _p_Gosu__Image
          :center: 0.5
        parent: *20832876
        paused: false
        visible: true
        image: *20828004
        color: !ruby/object:Gosu::Color
          __swigtype__: _p_Gosu__Color
        mode: :default
        x: 629.5570504584946
        y: 539.9016994374947
        zorder: 10
        angle: 144.0
        factor_y: 2
        factor_x: 2
        factor: 2
        center_x: 0.5
        center_y: 0.5
        title: OPTIONS
        action: !ruby/object:Proc {}
      - !ruby/object:PlanetDefense::RingMenu::Icon
        options:
          :scale: 2
          :zorder: 10
          :image: &20828100 !ruby/object:Gosu::Image
            __swigtype__: _p_Gosu__Image
          :center: 0.5
        parent: *20832876
        paused: false
        visible: true
        image: *20828100
        color: !ruby/object:Gosu::Color
          __swigtype__: _p_Gosu__Color
        mode: :default
        x: 702.2113032590307
        y: 428.0983005625053
        zorder: 10
        angle: 72.0
        factor_y: 2
        factor_x: 2
        factor: 2
        center_x: 0.5
        center_y: 0.5
        title: HIGH SCORES
        action: !ruby/object:Proc {}
      step: 0
      input:
        :left_arrow:
        - !ruby/object:Method {}
        :holding_left_arrow:
        - !ruby/object:Method {}
        :right_arrow:
        - !ruby/object:Method {}
        :holding_right_arrow:
        - !ruby/object:Method {}
        :return:
        - !ruby/object:Method {}
        :released_escape: []
        :released_right_arrow: []
      cursor: !ruby/object:Chingu::GameObject
        options:
          :scale: 2.5
          :image: &20828172 !ruby/object:Gosu::Image
            __swigtype__: _p_Gosu__Image
          :zorder: 5
        parent: *20832876
        paused: false
        visible: true
        image: *20828172
        color: !ruby/object:Gosu::Color
          __swigtype__: _p_Gosu__Color
        mode: :default
        x: 512
        y: 359
        zorder: 5
        angle: 0
        factor_y: 2.5
        factor_x: 2.5
        factor: 2.5
        center_x: 0.5
        center_y: 0.5
      count: 5
      game_state_manager: *22575264
    - &21041148 !ruby/object:PlanetDefense::SaveGame
      options: {}
      game_objects: !ruby/object:Chingu::GameObjectList
        game_objects:
        - &21040788 !ruby/object:PlanetDefense::TextInput
          options:
            :x: 412
            :y: 384
            :width: 200
            :height: 48
            :font: &21040956 !ruby/object:Gosu::Font
              __swigtype__: _p_Gosu__Font
          parent: *21041148
          paused: false
          visible: true
          color: !ruby/object:Gosu::Color
            __swigtype__: _p_Gosu__Color
          mode: :default
          x: 412
          y: 384
          zorder: 100
          angle: 0
          factor_y: 1
          factor_x: 1
          factor: 1
          center_x: 0.5
          center_y: 0.5
          width: 200
          height: 48
          font: *21040956
          text: !ruby/object:Chingu::Text
            size: 15
            options:
              :rotation_center: :top_left
              :x: 412
              :y: 384
            parent: *21041148
            paused: false
            visible: true
            color: !ruby/object:Gosu::Color
              __swigtype__: _p_Gosu__Color
            mode: :default
            x: 412
            y: 384
            zorder: 100
            angle: 0
            factor_y: 1
            factor_x: 1
            factor: 1
            center_x: 0
            center_y: 0
            text: asdf
            font: Arial
            line_spacing: 1
            align: :left
            max_width: !!null 
            padding: 5
            gosu_font: *20826948
            image: !ruby/object:Gosu::Image
              __swigtype__: _p_Gosu__Image
          rect:
          - 392
          - 372
          - 200
          - 48
        visible_game_objects:
        - *21040788
        unpaused_game_objects:
        - *21040788
      input_clients: []
      previous_game_state: *20827872
      font: *21040956
      text_input: *21040788
      background_image: !ruby/object:Gosu::Image
        __swigtype__: _p_Gosu__Image
      title_image: !ruby/object:Gosu::Image
        __swigtype__: _p_Gosu__Image
      selected: !ruby/object:Gosu::Color
        __swigtype__: _p_Gosu__Color
      current: 0
      menu_options:
      - :save game
      - :back
      input:
        :up_arrow:
        - !ruby/object:Method {}
        :down_arrow:
        - !ruby/object:Method {}
        :left_arrow:
        - !ruby/object:Method {}
        :right_arrow:
        - !ruby/object:Method {}
        :return:
        - !ruby/object:Method {}
        :released_return: []
        :a: []
        :s: []
        :d: []
        :f: []
        :released_a: []
        :released_s: []
        :released_d: []
        :released_f: []
      game_state_manager: *22575264
      color: !ruby/object:Gosu::Color
        __swigtype__: _p_Gosu__Color
      rect:
      - 0
      - 522
      - 1024
      - 36.0
    transitional_game_state: !!null 
    transitional_game_state_options: {}
player: &20832516 !ruby/object:PlanetDefense::Player
  vel_max: 7
  acceleration: 1
  deceleration: 0.95
  vel_y: 0.0
  vel_x: 0.0
  x: 512.0
  y: 718.0
  image: !ruby/object:Gosu::Image
    __swigtype__: _p_Gosu__Image
  font: !ruby/object:Gosu::Font
    __swigtype__: _p_Gosu__Font
  particles: !ruby/object:Chingu::Animation
    loop: true
    bounce: false
    file: media/gfx/fireball.png
    index: 0
    delay: 100
    step: 1
    dt: 0
    sub_animations: {}
    frame_actions: []
    width: 32
    height: 32
    frames:
    - !ruby/object:Gosu::Image
      __swigtype__: _p_Gosu__Image
    - !ruby/object:Gosu::Image
      __swigtype__: _p_Gosu__Image
    - !ruby/object:Gosu::Image
      __swigtype__: _p_Gosu__Image
    - !ruby/object:Gosu::Image
      __swigtype__: _p_Gosu__Image
  weapon: !ruby/object:PlanetDefense::Weapon
    player: *20832516
    cooldown_rate: 20
    heatup_amount: 7
    fire_rate: 85
    overheat_penalty: 800
    last_shot: 0
    last_cooldown: 437667665
    last_overheat: 0
    heat: 0
    overheated: false
    gauge_color: !ruby/object:Gosu::Color
      __swigtype__: _p_Gosu__Color
level:
  :number: 0
  :background_image: &20831460 !ruby/object:Gosu::Image
    __swigtype__: _p_Gosu__Image
  :background_music: &20831412 !ruby/object:Gosu::Song
    __swigtype__: _p_Gosu__Song
  :time: 15000
background_image: *20831460
music: *20831412
planet_health: 1000
lives: 3
life_image: !ruby/object:Gosu::Image
  __swigtype__: _p_Gosu__Image
font: !ruby/object:Gosu::Font
  __swigtype__: _p_Gosu__Font
health_font: !ruby/object:Gosu::Font
  __swigtype__: _p_Gosu__Font
count: 13
pause: true
running: true
win: false
hit: false
game_start: 437666494
time_allowed: 15000
menu: *20827872
game_state_manager: *22575264
input:
  :released_return: []
remaining_time: 13830

Upvotes: 1

Views: 2086

Answers (1)

fearless_fool
fearless_fool

Reputation: 35219

I just went down a similar path. Look in your YAML file for lines of the form:

action: !ruby/object:Proc {}

YAML can't deal with lambdas or procs (there's no sensible way to serialize them). If you have access to the code that generated the YAML'd object, perhaps you can replace the lambdas with an actual object and method call?

For instance, if the code that generated this YAML dump:

icon = PlanetDefense::RingMenu::Icon.new
icon.action = lambda {|arg1| do_something_with(arg1)}

You might be able to write a class whose sole job is to replace the lambda:

class IconAction
  def call(arg1)
    do_something_with(arg1)
  end
end
...
icon = PlanetDefense::RingMenu::Icon.new
icon.action = IconAction.new

Upvotes: 2

Related Questions