# Dry::Struct does not support initialize with keyword arguments

**URL:** <https://discourse.dry-rb.org/t/dry-struct-does-not-support-initialize-with-keyword-arguments/1692>\
**Category:** Support\
**Created:** [June 14, 2023, 3:13pm UTC](https://discourse.dry-rb.org/t/dry-struct-does-not-support-initialize-with-keyword-arguments/1692 "2023-06-14T15:13:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![nunocarvalhog](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/nunocarvalhog/32/890_2.png) [@nunocarvalhog](https://discourse.dry-rb.org/u/nunocarvalhog)\
**Post date:** [June 14, 2023, 3:13pm UTC](https://discourse.dry-rb.org/t/dry-struct-does-not-support-initialize-with-keyword-arguments/1692/1 "2023-06-14T15:13:48Z")

</div>

Having the following class:

```auto
class URL < Dry::Struct
  attr_reader :description
  attr_reader :url

  def initialize(description:, url:)
    @description = description
    @url = url
  end
end

```

And the code:

```auto
example_url = URL.new(description: "Example website", url: "https://example.com")

```

Fails with:

```auto
`initialize': wrong number of arguments (given 1, expected 0; required keywords: description, url) (ArgumentError)

```

Is it expected? Are keyword arguments not supported when using dry-struct?

---

<div class="post-metadata">

**Author:** ![alassek](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/alassek/32/314_2.png) [@alassek](https://discourse.dry-rb.org/u/alassek)\
**Post date:** [June 15, 2023, 9:02pm UTC](https://discourse.dry-rb.org/t/dry-struct-does-not-support-initialize-with-keyword-arguments/1692/2 "2023-06-15T21:02:36Z")

</div>

Keyword arguments work fine, you’re having trouble because you’re not using the struct interface at all.

```ruby
require 'dry/types'
require 'dry/struct'
require 'uri'

Types = Dry.Types(default: :strict)

module Types
  URL = Instance(URI::Generic).constructor { URI(_1) }
end

class URL < Dry::Struct
  attribute :description, Types::String
  attribute :url, Types::URL
end

URL.new(description: "Example website", url: "https://example.com")
# => #<URL description="Example website" url=#<URI::HTTPS https://example.com>>

```

---

<div class="post-metadata">

**Author:** ![alassek](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/alassek/32/314_2.png) [@alassek](https://discourse.dry-rb.org/u/alassek)\
**Post date:** [June 15, 2023, 9:26pm UTC](https://discourse.dry-rb.org/t/dry-struct-does-not-support-initialize-with-keyword-arguments/1692/3 "2023-06-15T21:26:09Z")

</div>

The more involved answer to your question is that defining your own `initialize` is almost never necessary, and what you are trying to do in the example would not work.

`Struct::new` collects the incoming attributes and performs a schema validation against your `::schema` object (try inspecting `URL.schema` to see it). Anything that has not been declared with `attribute` will be discarded before `initialize` is even called.

So if you actually wanted to implement `initialize`, first of all you need to call `super`. And secondly, it will receive a single hash of attributes because that is the output of the schema validation.
