Skip to content

Superclasses, Children and unexpected results (self is not what it should be) #41

@PragTob

Description

@PragTob

Hi there!

First, thanks a lot for your work! 💚

Problematic Script

require "docile"

class Parent
  attr_reader :children

  def initialize
    @children = []
  end

  def add_child(clazz, &block)
    child = clazz.new
    children << child

    Docile.dsl_eval(child, &block) if block
    child
  end
end

class CustomParent < Parent
  def do_stuff
    add_child Parent do
      wanna_be_custom
    end
  end

  def wanna_be_custom
    add_child CustomParent
  end
end

parent = CustomParent.new
parent.do_stuff

p parent.children

Actual Output

Both Children are added to the main parent/within the block self isn't shifted to the child

[#<Parent:0x000055794759c598 @children=[]>, #<CustomParent:0x00005579475ab7a0 @children=[]>]

Expected Output

the main parent has one child, which itself then has the CustomParent as a child. (within the block self correctly is the child)

[#<Parent:0x000055d997c50460 @children=[#<CustomParent:0x000055d997c5b658 @children=[]>]>]

This output can currently be achieved in 2 ways:

  1. inline wanna_be_custom
  def do_stuff
    add_child Parent do
      add_child CustomParent
    end
  end
  1. in add_child, instead of instantiating the passed in class just use self.class (yes this changes semantics but might give a hint as to the source of this)
  def add_child(clazz, &block)
    child = self.class.new
    children << child

    Docile.dsl_eval(child, &block) if block
    child
  end

Might be related to #31 but it's marked fixed 🤷‍♂️

edit: After a good night sleep I finally realized that of course this is about self being the wrong thing so much like #31 ;)

Metadata

Metadata

Assignees

No one assigned

    Labels

    2.0Feature request for 2.0

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions