I am reading about SOLID principles. In Ruby tutorials and code samples, I often see subclass extensions like:

class House
  attr_reader :items

class Room < House
  attr_reader :chair

p House.chair = 'baroque_style'# => NoMethodError

Of course the examples are useful to show how easily classes are manipulate in ruby, but isn't this a violation of the Liskov Substitution Principle?

  • 3
    Saying that a woman is less than a person is not funny. – coredump Oct 27 '15 at 17:30
  • Sorry, that came out badly, there was no intention of insulting women or anyone else for the matter. I changed the code sample, thanks for pointing that out. – atmosx Oct 27 '15 at 18:12
  • Sorry, I was intended to be taken as a second degree joke. Next time I'll be less subtle ಠ_ಠ. I hope I did not scare you. ​​​​​​​​​​​​ – coredump Oct 27 '15 at 18:29
  • 1
    I didn't get the sarcasm, but I prefer this example anyway. At this age and time IMHO is wiser to avoid this kind of misunderstandings. – atmosx Oct 27 '15 at 18:51
  • Side note, usually this should be true: DerivedClass is a BaseClass. In your example Room is a House is not true, which should raise a red flag. – Matthew James Briggs Oct 28 '15 at 3:48

No, LSP states that if S is a subtype of T, you should be able to use an S whenever a T is expected.

In your example, Room is a subtype of House, so we should be able to pass an instance of Room to anything expecting a House. What you then do is to pass a House into code expecting a Room (so you are using a T, where an S is expected).

  • Thanks for clarifying. So - to make sure I understood the principle - a violation will happen if we choose to override a method defined in T by re-defining it on class S? (e.g. if T.method1.is_a? String and S.method1.is_a? FixNum) – atmosx Oct 27 '15 at 18:22
  • 1
    Your comment is very misleading. It's not about the methods that T and S respond to, it's about the methods that instances of S and T respond to. The important thing about the LSP is the history rule. The fact that the subtyping relationship between function types is contravariant in the subtyping relationship of the argument types and covariant in the subtyping relationship of the return types was well-known long before that (and is kind-of obvious anyway). The novel contribution of the LSP is a) the formulation in terms of substitutability and b) the history rule, which makes … – Jörg W Mittag Oct 27 '15 at 20:31
  • … it applicable to mutable types with identity, whereas the earlier formulation in terms of variance of function types only ever considered pure functions. – Jörg W Mittag Oct 27 '15 at 20:32
  • @JörgWMittag sorry but I do not understand the basic concept here. I need to study and see some real world examples. My point is that I cant follow your reasoning, unfortunately. Thanks, at least you showed me that I totally missed the point, I must go to square one. – atmosx Oct 27 '15 at 20:53
  • I suspect Cat and Mammal are better examples than Room and House. Sub-classes should, in general, follow an "is-a" relation (so, neither a "has-a" or "exists-in"). – Vatine Oct 28 '15 at 11:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.