Skip to content

[breaking] ostruct dependency introduced in 1.4.1 breaks dragonfly as it has stricter handling of internals than Ruby stdlib version #528

@mrIllo

Description

@mrIllo

ostruct from RubyGems (like 0.6.1) is stricter than the built-in stdlib version — especially in how it handles .dup, initialize_copy, and internal coercion like to_sym.
Dragonfly’s usage of OpenStruct worked fine with the stdlib version, but not with the gem version.
So even though the gem was added for future Ruby 3.5 compatibility, it breaks behavior today under Ruby 3.0–3.2.

How to reproduce:
It took me a whole day to narrow it down to this.

  1. I have added a processor :cropped_overlay_teaser, MyProcessor in my config
  2. class MyProcessor is the wrapper (with call(content, size) ) around Dragonfly::ImageMagick::Commands.convert(content,....)
  3. in my class PicturesApp < Dragonfly::RoutedEndpoint I do
  ...
  picture = @app.fetch_file(@fetch_file)
  picture = picture.cropped_overlay_teaser(@size)
  ...
  1. when using you get this strange error:
undefined method `to_sym' for false:FalseClass
Did you mean?  to_s
stack trace: /var/lib/gems/3.0.0/gems/ostruct-0.6.1/lib/ostruct.rb:319:in `[]='
/var/lib/gems/3.0.0/gems/ostruct-0.6.1/lib/ostruct.rb:160:in `block in update_to_values!'
/var/lib/gems/3.0.0/gems/ostruct-0.6.1/lib/ostruct.rb:159:in `each_pair'
/var/lib/gems/3.0.0/gems/ostruct-0.6.1/lib/ostruct.rb:159:in `update_to_values!'
/var/lib/gems/3.0.0/gems/ostruct-0.6.1/lib/ostruct.rb:154:in `initialize_dup'
/var/lib/gems/3.0.0/gems/dragonfly-1.4.1/lib/dragonfly/job.rb:95:in `dup'
/var/lib/gems/3.0.0/gems/dragonfly-1.4.1/lib/dragonfly/job.rb:95:in `initialize_copy'
(eval):3:in `initialize_dup'
(eval):3:in `dup'
(eval):3:in `process'
/var/lib/gems/3.0.0/gems/dragonfly-1.4.1/lib/dragonfly/app.rb:153:in `block in add_processor'
  1. in job.rb there is initialize_copy where I added debug code to show the problem:
    def initialize_copy(other)
      @steps = other.steps.map do |step|
        step.class.new(self, *step.args)
      end
      @content = other.content.dup
puts "DEBUG other.url_attributes=#{other.url_attributes.to_h}"
      @url_attributes = other.url_attributes.dup
    end
  1. with ostruct gem 0.6.x this shows you
    DEBUG other.url_attributes={:name=>"myfilename.jpg", false=>"myfilename.jpg"}

while with stdlib ostruct you see the expected:
DEBUG other.url_attributes={:name=>"myfilename.jpg"}

  1. I could not narrow it down to why this different behavior happens, as I did not have the time to investigate when and how the internal url_attributes are set in that case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions