# Call a method on parent thats also defined on the child from a different method

**URL:** <https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493>\
**Category:** Help & Support\
**Created:** [July 10, 2021, 2:22pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493 "2021-07-10T14:22:33Z")\
**Posts on this page:** 14\
**Page:** 1

<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:** [July 10, 2021, 2:22pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/1 "2021-07-10T14:22:33Z")

</div>

I can’t seem to figure out a way to call a parent class’s implementation of a method from a different method and when that parent method is also redefined in the child. For example:

```auto
abstract class Foo
  def one
    "One"
  end
 
  def two
    "Two"
  end
end
 
class Bar < Foo
  def three
    one
  end
 
  def one
    "1"
  end
end
 
b = Bar.new
 
# This should print One
pp b.three

```

[https://play.crystal-lang.org/#/r/bfrz](https://play.crystal-lang.org/#/r/bfrz)

You can’t just use `self.one` as that uses the child’s implementation. `::one` doesn’t work as it looks for it on the top level. `super.one` errors with `undefined method 'three' for Object` (although this does work in Java). In PHP you could do `parent::one();` , which is basically the same as Java with a different keyword.

We probably should allow calling a different method on `super` versus just having it assume the method you want is the one you’re calling it from?

---

<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:** [July 10, 2021, 3:14pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/2 "2021-07-10T15:14:41Z")

</div>

You can’t do this either in Ruby. The way to do it is to make one call a helper method, and then call that helper method from the child class.

---

<div class="post-metadata">

**Author:** ![drhuffman12](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/drhuffman12/32/715_2.png) [@drhuffman12](https://forum.crystal-lang.org/u/drhuffman12)\
**Post date:** [July 10, 2021, 4:07pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/3 "2021-07-10T16:07:22Z")

</div>

This feels kinds hacky, but if you make `Foo` to be not `abstract` and if you don’t mind ‘escaping’ the ‘instance’ level of your `Bar` object, then you can do `{{@type.superclass}}.new.one` as noted in [Carcin](https://play.crystal-lang.org/#/r/bion/edit) . You could maybe do something like `{{@type.superclass}}.new(self.param_xyz).one` if you want to keep some instance data, but that still seems a bit hacky.

---

<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:** [July 10, 2021, 4:24pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/4 "2021-07-10T16:24:41Z")

</div>

> [@asterite](#):
>
> You can’t do this either in Ruby.

Is there a reason this isn’t supported? Or just something that hasn’t been implemented yet?

> [@drhuffman12](#):
>
> This feels kinds hacky, but

This is definitely hacky ha. Fortunately in my case the parent method was pretty trivial, so i just copied the code from there into the child directly.

---

<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:** [July 10, 2021, 4:39pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/5 "2021-07-10T16:39:36Z")

</div>

The reason is Ruby: you can’t do it in Ruby. In my mind whenever you need to do this is a small. Could you expand more on the real use case?

---

<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:** [July 10, 2021, 5:05pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/6 "2021-07-10T17:05:21Z")

</div>

The gist of it is I was porting some PHP code and that’s how they had things setup. Specifically [symfony/ConsoleSectionOutput.php at 5.4 · symfony/symfony · GitHub](https://github.com/symfony/symfony/blob/5.4/src/Symfony/Component/Console/Output/ConsoleSectionOutput.php#L61).

The parent abstract type defines `write` and `writeln` akin to our `print` and `puts` methods as well as an abstract `doWrite` that defers _how_ to do the writing depending on the child. In this case the direct parent type is for stream (IO) based output which will write the data to the stream.

The type from the link above extends the stream based type overriding `doWrite` as it has some additional logic within it. In some cases it calls `parent::doWrite("some string", false);` to simply write the data, avoiding the extra logic in the child type. It also doesn’t use `write` or `writeln` as those do some additional formatting to the data and would still invoke the child’s implementation. Because the content is already in its final form it can just utilize the parent’s implementation.

Granted in this case it’s not a big deal as the parent `do_write` in Crystal land is just `new_line ? @io.puts(message) : @io.print(message)`. But I don’t see why it shouldn’t be a feature just because it’s not in Ruby. We already have the `super` keyword. Continue to have `super ...` refer to the method it’s called in but also allow calling methods on it like `super.do_write "foo", false`.

---

<div class="post-metadata">

**Author:** ![HertzDevil](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hertzdevil/32/1023_2.png) [@HertzDevil](https://forum.crystal-lang.org/u/HertzDevil)\
**Post date:** [August 22, 2021, 5:46pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/7 "2021-08-22T17:46:11Z")

</div>

If there are any positional parameters in the defs, a different hack is to give them different names:

```crystal
abstract class Foo
  def one(x)
    "One"
  end
end
 
class Bar < Foo
  def three
    one(x: ...)
  end
 
  def one(y)
    "1"
  end
end

Bar.new.three # => "One"

```

---

<div class="post-metadata">

**Author:** ![HertzDevil](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hertzdevil/32/1023_2.png) [@HertzDevil](https://forum.crystal-lang.org/u/HertzDevil)\
**Post date:** [June 20, 2022, 3:32pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/8 "2022-06-20T15:32:54Z")

</div>

> [@asterite](#):
>
> You can’t do this either in Ruby.

It turns out you can with some reflection:

```ruby
class Foo
  def one
    "One"
  end
 
  def two
    "Two"
  end
end
 
class Bar < Foo
  def three
    self.class.superclass.instance_method(:one).bind(self).call
  end
 
  def one
    "1"
  end
end
 
b = Bar.new
 
p b.three # => "One"

```

---

<div class="post-metadata">

**Author:** ![zw963](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/zw963/32/1623_2.png) [@zw963](https://forum.crystal-lang.org/u/zw963)\
**Post date:** [June 20, 2022, 5:04pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/9 "2022-06-20T17:04:51Z")

</div>

> [@Blacksmoke16](#):
>
> `super.one` errors with `undefined method 'three'`

you can’t invoke super.one even you define three in parent class.

be cause super in ruby (so should in crystal too) just invoke same name method in parent class with same args, it not a parent class object?

---

<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:** [June 21, 2022, 10:50pm UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/10 "2022-06-21T22:50:36Z")

</div>

> [@zw963](#):
>
> because super in ruby (so should in crystal too) just invoke same name method in parent class with same args

I’m not sure I agree with the argument that something in Crystal should behave in a particular way just because that’s how it works in Ruby. Crystal and Ruby _are_ separate languages, so we should look at the other points of view when considering if a feature should or should not be added.

Other languages support it, so it’s not out of the question to want this feature in Crystal too. Granted it’s not super critical/often needed, but still could be a nice to have just to avoid the extra boilerplate of needing another helper method.

---

<div class="post-metadata">

**Author:** ![I3oris](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/i3oris/32/1106_2.png) [@I3oris](https://forum.crystal-lang.org/u/I3oris)\
**Post date:** [June 23, 2022, 12:53am UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/11 "2022-06-23T00:53:29Z")

</div>

I like the idea having this in crystal too. I had the need one time.

I wonder what would be the syntax?

The most intuitive is `super.one()` but `super` alone is already taken. But maybe we could allow it and force using `(super).foo` to disambiguate ? (this would be a breaking change though…, but for 2.0?)

---

<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:** [June 23, 2022, 12:57am UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/12 "2022-06-23T00:57:33Z")

</div>

Probably could do something like seeing the method call has a receiver of `super` and parse that differently than when its by itself/a simple call?

---

<div class="post-metadata">

**Author:** ![zw963](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/zw963/32/1623_2.png) [@zw963](https://forum.crystal-lang.org/u/zw963)\
**Post date:** [June 23, 2022, 6:44am UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/13 "2022-06-23T06:44:04Z")

</div>

Please check [Inheritance - Crystal](https://crystal-lang.org/reference/1.4/syntax_and_semantics/inheritance.html#super)

Sure it need following the design from ruby, because it involves others things in ruby

Dart use `super.one()` hack, when i start o write flutter the first time, i even misunderstood the means of super.

anyway, i don’t think crystal need/will change this in the future, it just work like this.

---

<div class="post-metadata">

**Author:** ![zw963](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/zw963/32/1623_2.png) [@zw963](https://forum.crystal-lang.org/u/zw963)\
**Post date:** [June 23, 2022, 6:46am UTC](https://forum.crystal-lang.org/t/call-a-method-on-parent-thats-also-defined-on-the-child-from-a-different-method/3493/14 "2022-06-23T06:46:56Z")

</div>

That totally make user confusing … 🤣
