Git Product home page Git Product logo

Comments (7)

sevos avatar sevos commented on August 19, 2024 2

Thanks for clarification

from dry-struct.

sevos avatar sevos commented on August 19, 2024

Monkey-patch fix:

class Dry::Struct
  undef_method :to_hash

  def to_h
    self.class.schema.keys.each_with_object({}) do |key, result|
      result[key] = Hashify[self[key]]
    end
  end
end

But I am not 100% of the implications of it

from dry-struct.

flash-gordon avatar flash-gordon commented on August 19, 2024

Yeah, I know that, this is how ruby works, they really messed with it IMO. Structs are supposed to work as hashes so this is expected. I wouldn't go with a monkey patch though, you can subclass Dry::Struct and use it as a base where you need

class MyStruct < Dry::Struct
  undef_method :to_hash
end

^also, you don't need to override to_h, undefining of to_hash doesn't affect it.

from dry-struct.

sevos avatar sevos commented on August 19, 2024

You say "Structs are supposed to work as hashes", but I wonder where is this requirement coming from.

In Ruby neither Struct nor OpenStruct implements the implicit conversion method to_hash. Both implement the explicit conversion method #to_h
More on the differences between implicit and explicit conversion methods here.

irb(main):001:0> A = Struct.new(:a, :b)
=> A
irb(main):002:0> def iii(**kwargs)
irb(main):003:1> puts kwargs
irb(main):004:1> end
=> :iii
irb(main):005:0> iii A.new(1,2)
Traceback (most recent call last):
        3: from /Users/sevos/.rbenv/versions/2.5.0/bin/irb:11:in `<main>'
        2: from (irb):5
        1: from (irb):2:in `iii'
ArgumentError (wrong number of arguments (given 1, expected 0))
irb(main):006:0> iii A.new(1,2).to_h
{:a=>1, :b=>2}
=> nil
irb(main):009:0> iii OpenStruct.new(a: 1, b: 2)
Traceback (most recent call last):
        3: from /Users/sevos/.rbenv/versions/2.5.0/bin/irb:11:in `<main>'
        2: from (irb):9
        1: from (irb):2:in `iii'
irb(main):010:0> iii OpenStruct.new(a: 1, b: 2).to_h
{:a=>1, :b=>2}
=> nil
irb(main):007:0>

I am afraid that there may be more cases when the struct may be deconstructed into a hash prematurely or accidentally causing us to lose the information about the type of the data it carries. Please tell me what are the cases you find this behaviour useful? Maybe there is really more good than harm...
Personally I use Dry::Struct as a base class for business domain entities and it's more of a better-Struct than a better-Hash, so I would prefer not to deconstruct these objects easily. Of course there should be a way to convert it to a hash, when needed.

Thanks for the idea for the base class, but now I worry more about dry-struct compatibility with other libraries, which may deconstruct it accidentally.

from dry-struct.

flash-gordon avatar flash-gordon commented on August 19, 2024

This is not a requirement, this is a design choice. One quick example is rom's interface for writing data, it relies on coercions made by Hash[value], anything hash-like can be passed in, including structs.

from dry-struct.

abrthel avatar abrthel commented on August 19, 2024

For the record, this also just bit me. I was definitely not expecting my entity object to deconstruct into a hash because I had a keyword arg in a composite class initializer.

from dry-struct.

kke avatar kke commented on August 19, 2024

FYI: This does not even require **kwargs, regular keyword arguments are enough.

def display(*items, color: true)
  puts "items: %p color: %p" % [items, color]
end

Calling this with a Dry::Struct causes: ArgumentError : unknown keywords: item_attribute, item_attribute2, item_attribute_x

There's an issue (that originated from using Dry::Validation :)) at https://bugs.ruby-lang.org/issues/14909 and they suggest "just wait for ruby 3"

from dry-struct.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.