How can we call parent's parent method in Ruby(elegant way)?

Hi All,
How better can I design the below problem :
class Animal def move "I can move" endend
class Bird < Animal def move super + " by flying" endend
class Ostrich < Bird def move m = Animal.instance_method(:move).bind(self) m.call << ' by swimming' endend
Ostrich.new.move # => "I can move by swimming"
This is a working code. But the solution is not good, it seems like a brute force. Regards,
Arup Rakshit

That should give you an indication that what you are attempting here is
probably not the right approach. In this particular case template method
pattern seems more appropriate:

class Animal
  def move
    "I can move by " + move_method
  end

end

class Bird < Animal
protected
  def move_method
    'flying'
  end
end

class Ostrich < Bird
protected
  def move_method
    'swimming'
  end
end

Ostrich.new.move # => "I can move by swimming"

Kind regards

robert

···

On Wed, Jan 21, 2015 at 7:29 AM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

Hi All,

How better can I design the below problem :

class Animal
  def move
    "I can move"
  end
end

class Bird < Animal
  def move
    super + " by flying"
  end
end

class Ostrich < Bird
  def move
    m = Animal.instance_method(:move).bind(self)
    m.call << ' by swimming'
  end
end

Ostrich.new.move # => "I can move by swimming"

This is a working code. But the solution is not good, it seems like a
brute force.

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

Hello,

Hi All,

How better can I design the below problem :

class Animal
  def move
    "I can move"
  end
end

class Bird < Animal
  def move
    super + " by flying"
  end
end

class Ostrich < Bird
  def move
    m = Animal.instance_method(:move).bind(self)
    m.call << ' by swimming'
  end
end

IMHO the above example feels like poor design in Ruby. One should be using modules or mixins in order to avoid situations like this situation. However, I wouldn’t be able (from he top of my head) to put together "Animal.instance_method(:mode).bind(self)” so thanks for the heads up :slight_smile:

Ostrich.new.move # => "I can move by swimming"

This is a working code. But the solution is not good, it seems like a brute force.

Regards,
Arup Rakshit

Panagiotis (atmosx) Atmatzidis

email: atma@convalesco.org
URL: http://www.convalesco.org
GnuPG ID: 0x1A7BFEC5
gpg --keyserver pgp.mit.edu --recv-keys 1A7BFEC5

"As you set out for Ithaca, hope the voyage is a long one, full of adventure, full of discovery [...]" - C. P. Cavafy

···

On 21 Jan 2015, at 08:29, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

That should give you an indication that what you are attempting here is probably not the right approach. In this particular case template method pattern seems more appropriate:

class Animal def move "I can move by " + move_method end
end
class Bird < Animalprotected def move_method 'flying' endend
class Ostrich < Birdprotected def move_method 'swimming' endend
Ostrich.new.move # => "I can move by swimming"

Robert,
Thanks.
Excellent approach. I knew it can be solved elegantly, and you did it. Only one question - Why not **private**, instead you made them **protected** method?

THIS is elegant
thanks robert!

···

On 21/01/15 10:56, Robert Klemme wrote:

That should give you an indication that what you are attempting here is probably not the right approach.
In this particular case template method pattern seems more appropriate:

class Animal def move "I can move by " + move_method end

end

class Bird < Animal protected def move_method 'flying' end end

class Ostrich < Bird protected def move_method 'swimming' end end

Ostrich.new.move # => "I can move by swimming"

Kind regards

robert

Mostly out of habit: in Java I would have defined the method "abstract
protected" at the base class level. In Ruby private would work as well - or
might be even better.

Kind regards

robert

···

On Wed, Jan 21, 2015 at 11:10 AM, Arup Rakshit <aruprakshit@rocketmail.com> wrote:

Excellent approach. I knew it can be solved elegantly, and you did it.
Only one question - Why not **private**, instead you made them
**protected** method?

--
[guy, jim].each {|him| remember.him do |as, often| as.you_can - without end}
http://blog.rubybestpractices.com/

Suppose you have this method:

class Animal
  def moves_like_me?(other_animal)
    other_animal.move_method == move_method
  end
end

This works when #move_method is protected (instances of
the same class can call the method from the outside),
but not when it's private.

···

On Wed, 21 Jan 2015 10:10:45 +0000 (UTC) Arup Rakshit <aruprakshit@rocketmail.com> wrote:

Excellent approach. I knew it can be solved elegantly, and you did it. Only one question - Why not **private**, instead you made them **protected** method?

Humm, Perfectly makes sense.

···

On Wednesday, January 21, 2015 01:40:27 PM you wrote:

On Wed, 21 Jan 2015 10:10:45 +0000 (UTC) > Arup Rakshit <aruprakshit@rocketmail.com> wrote:

> Excellent approach. I knew it can be solved elegantly, and you did it. Only one question - Why not **private**, instead you made them **protected** method?
>
>

Suppose you have this method:

class Animal
  def moves_like_me?(other_animal)
    other_animal.move_method == move_method
  end
end

This works when #move_method is protected (instances of
the same class can call the method from the outside),
but not when it's private.

--

Regards,
Arup Rakshit

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

--Brian Kernighan