# New / Initialize hook?

**URL:** <https://forum.crystal-lang.org/t/new-initialize-hook/3223>\
**Category:** Help & Support\
**Created:** [April 19, 2021, 10:47am UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223 "2021-04-19T10:47:00Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![nico](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nico/32/692_2.png) [@nico](https://forum.crystal-lang.org/u/nico)\
**Post date:** [April 19, 2021, 10:47am UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/1 "2021-04-19T10:47:00Z")

</div>

hello,

I’m looking for a way to execute code when creating an instance. For example from a module, this is to avoid having to call a method (init\_my\_module) in each initialize including this module. In the principle of `#finalize` (or `GC.add_finalizer`) but for the initialization.

Is there a way (std or not) to do this in Crystal?

---

<div class="post-metadata">

**Author:** ![jhass](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/jhass/32/1779_2.png) [@jhass](https://forum.crystal-lang.org/u/jhass)\
**Post date:** [April 19, 2021, 10:52am UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/2 "2021-04-19T10:52:39Z")

</div>

`initialize` is a regular method for the most part, so normal inheritance rules apply for the most part: [Carcin](https://carc.in/#/r/ax6e) But this might a little less magic than you’re looking for…

I could imagine some more magic is achievable with `macro included` overriding `initialize` to call `super` and the original with `previous_def`, but not sure that’s worth the complexity.

---

<div class="post-metadata">

**Author:** ![nico](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nico/32/692_2.png) [@nico](https://forum.crystal-lang.org/u/nico)\
**Post date:** [April 19, 2021, 11:20am UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/3 "2021-04-19T11:20:23Z")

</div>

The difficulty in overriding `initialize` is when there are several with different signatures [Carcin](https://carc.in/#/r/ax6h). Of course there is a way to put a state in `init_my_module` to avoid initializing several times when an initialize call another initialize. Also, by using the macro `finished` into the macro `included` and overriding each initialize (+ take care of the hierarchy (child \< parent). It goes into the too complex.

If there is only one input source (a common method or a hook like finalize), it would be more convenient and easier to debug.

Via GC you think it’s possible? Like a `GC.add_initializer` or other.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 19, 2021, 11:58am UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/4 "2021-04-19T11:58:21Z")

</div>

What do you need to initialize exactly?

---

<div class="post-metadata">

**Author:** ![nico](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nico/32/692_2.png) [@nico](https://forum.crystal-lang.org/u/nico)\
**Post date:** [April 19, 2021, 1:55pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/5 "2021-04-19T13:55:43Z")

</div>

This is a module to handle configuration (from env, files, default values hard coded) and data validations. I need to do some processing on the values of instance variables.

Here is a simplified example:

```crystal
struct Config
  include Configurator

  entry url : String = "http://localhost:3000", {required: true, url: "Should be a valid URL"}
  # entry db_uri....
end

```

The `Configurator` module handle `ENV` hash and data validation. Example, if I provide `a bad url` to `url` entry, I get the error `Should be a valid URL`.

Currently, I have to add an initializer into each `initialize` methods.

```crystal
struct Config
  include Configurator

  entry url : String = "http://localhost:3000", {required: true, url: "Should be a valid URL"}
  # entry db_uri....

 def initialize 
   # I want to avoid this constraint by detecting the instance creation. 
   # Or another way without having to do anything other than include the module.
   init 
 end
end

```

Ideally, it would be convenient to include the module that works without setting a DSL. My example is for the config but this is the case for every class where I have to do some validation and some kind of ioc.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 19, 2021, 2:19pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/6 "2021-04-19T14:19:53Z")

</div>

What does `init` do?

---

<div class="post-metadata">

**Author:** ![nico](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nico/32/692_2.png) [@nico](https://forum.crystal-lang.org/u/nico)\
**Post date:** [April 19, 2021, 2:40pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/7 "2021-04-19T14:40:28Z")

</div>

> some processing on the values of instance variables

Like:

```auto
def init
   {% for var, entry in ENTRIES %}
      @{{var}} = check_{{var}}(@{{var}})
       # etc... on the instance variables
   {% end %}
end

```

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [April 19, 2021, 2:51pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/8 "2021-04-19T14:51:53Z")

</div>

If this is the path you want to go down, couldn’t you just do like:

```auto
def self.load
  instance = new
  instance.init
  instance
end

```

Have this method be added when the module is included then use it as the entrypoint versus the standard `.new`. Or could even make it `def self.new` if you want this to be the default behavior.

---

<div class="post-metadata">

**Author:** ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)\
**Post date:** [April 19, 2021, 2:52pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/9 "2021-04-19T14:52:02Z")

</div>

You could always initialize those lazily.

EDIT: Nevermind, maybe not.

---

<div class="post-metadata">

**Author:** ![nico](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nico/32/692_2.png) [@nico](https://forum.crystal-lang.org/u/nico)\
**Post date:** [April 19, 2021, 3:20pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/11 "2021-04-19T15:20:06Z")

</div>

> @asterite: You could always initialize those lazily.  
> EDIT: Nevermind, maybe not.

What do you mean?

@Blacksmoke16 Thanks. Indead, it’s a solution. However, that prevents from having a normal initialization (with `new`). If I define a `new`, like `initialize` it would be necessary to define several if there are several signatures.

---

<div class="post-metadata">

**Author:** ![nico](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nico/32/692_2.png) [@nico](https://forum.crystal-lang.org/u/nico)\
**Post date:** [April 19, 2021, 3:37pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/12 "2021-04-19T15:37:42Z")

</div>

ok, this seems to work

```crystal
def self.new
        instance = allocate
        instance.initialize if instance.responds_to?(:initialize)
        instance.init
        GC.add_finalizer(instance) if instance.responds_to?(:finalize)
        instance
      end

      def self.new(*args)
        instance = allocate
        instance.initialize(*args) if instance.responds_to?(:initialize)
        instance.init
        GC.add_finalizer(instance) if instance.responds_to?(:finalize)
        instance
      end

```

I hope I didn’t forget anything in the `new’ so as not to compromise the normal operation?

---

<div class="post-metadata">

**Author:** ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)\
**Post date:** [April 19, 2021, 4:48pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/13 "2021-04-19T16:48:41Z")

</div>

That’s a dangerous approach. You really shouldn’t hack into the allocation logic. It’s completely unnecessary and can easily break.

As @jhass already mentioned in the first comment, simply redefining the constructor method and delegating to `previous_def` should work very well for your use case.

```auto
module InitializeHook
  def initialize_hook
    puts "#{self} initialized"
  end
  
  macro included
    macro finished
      \{% for method in @type.methods %}
        \{% if method.name == "initialize" %}
          def initialize(\{{ method.args.join(",").id }})
            previous_def
            initialize_hook
          end
        \{% end %}
      \{% end %}
    end
  end
end

```

[https://carc.in/#/r/ax6z](https://carc.in/#/r/ax6z)

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [April 19, 2021, 5:03pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/14 "2021-04-19T17:03:49Z")

</div>

Personally I’m very against this pattern. While it makes for a nice DSL, the rest of the implementation is a bear. Is it not possible to decouple the instantiation of the type with the validation of the values? For example:

```auto
struct Config
  include Configurator

  entry url : String = "http://localhost:3000", {required: true, url: "Should be a valid URL"}
  # entry db_uri....

 def initialize(@url : String)
  # Call the method added via the module
  self.validate
 end
end

```

Having the validation be separate from setting the state of the type would be much more flexible, as it would inherently support multiple constructors. E.g. from `YAML` or `JSON`, etc. It also makes for much simpler code as you’re able to better leverage existing language semantics, versus essentially reimplementing the initializer logic.

You’d also be able to do away with `required` as the compiler would know/enforce that it cannot be nil. Or if you still want it could use the nilability of the entry’s type to know if it is or not.  
[Validator - Athena Framework](https://athenaframework.org/Validator/#Athena::Validator--validating-objects) Might be helpful as well if you want to go down this route.

---

<div class="post-metadata">

**Author:** ![nico](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/nico/32/692_2.png) [@nico](https://forum.crystal-lang.org/u/nico)\
**Post date:** [April 19, 2021, 6:59pm UTC](https://forum.crystal-lang.org/t/new-initialize-hook/3223/15 "2021-04-19T18:59:16Z")

</div>

@straight-shoota ah thank you, I didn’t understand it like this. It’s ok!

> @Blacksmoke16: Is it not possible to decouple the instantiation of the type with the validation of the values?

Yes, of course. It’s not just for the validation. My goal is to call a function even with several constructors, without having to add it to each one.

> @Blacksmoke16: You’d also be able to do away with `required` as the compiler would know/enforce that it cannot be nil. Or if you still want it could use the nilability of the entry’s type to know if it is or not.

It’s just an example. A validation rule to check from a Hash and generate the error message. Not related to the Crystal type.

Currently I use the validation like it:

```crystal
validation = User.check(json_h)
return validation.errors unless validation.valid?

```

But my question is not related to the validation and I know you validator because you posted it to me, forum and chat very frequently, but thanks again. 😌
