<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Object Mentor Blog: Tag LSP</title>
    <link>http://blog.objectmentor.com/articles/tag/lsp</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>Some Rough Draft TDD Demonstration Videos</title>
      <description>&lt;p&gt;I&amp;#8217;m doing a series of videos on &lt;span class="caps"&gt;TDD&lt;/span&gt;. The ultimate result will be a much more polished version with embedded slides, and such. But as a part of the development process, I&amp;#8217;m creating scratch videos.&lt;/p&gt;


	&lt;p&gt;Much of what you see in these videos will be in the final versions, but those are far in the future relative to this work.&lt;/p&gt;


	&lt;p&gt;Hope you find them interesting.&lt;/p&gt;


	&lt;p&gt;Comments welcome.&lt;/p&gt;


Here is what is already available:
	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://vimeo.com/10569751"&gt;Getting started&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://vimeo.com/10570537"&gt;Adding Operators&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


Next up:
	&lt;ul&gt;
	&lt;li&gt;Removing violation of Open/Closed principle&lt;/li&gt;
		&lt;li&gt;Removing duplication in operations with a combination of the Strategy pattern and the Template Method pattern&lt;/li&gt;
		&lt;li&gt;Adding new operators after the removal of duplication.&lt;/li&gt;
		&lt;li&gt;Reducing coupling by using the Abstract Factory pattern, Dependency Inversion and Dependency Injection&lt;/li&gt;
		&lt;li&gt;Adding a few more operations&lt;/li&gt;
		&lt;li&gt;Allowing the creation of complex &amp;#8220;programs&amp;#8221; or &amp;#8220;macros&amp;#8221; by using the Composite pattern &amp;#8211; and avoiding Liskov Substitution Principle inherent in the GoF version of the pattern&lt;/li&gt;
		&lt;li&gt;Driving the calculator via FitNesse + Slim&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Anyway, that&amp;#8217;s the plan. I&amp;#8217;ll try to add each of these videos over the next few weeks.&lt;/p&gt;</description>
      <pubDate>Tue, 30 Mar 2010 21:01:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:f9144f21-6bbf-4e5d-b525-9e526c000fe8</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2010/03/30/some-rough-draft-tdd-demonstration-videos</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>TDD</category>
      <category>bdd</category>
      <category>video</category>
      <category>demonstration</category>
      <category>design</category>
      <category>patterns</category>
      <category>SRP</category>
      <category>LSP</category>
      <category>OCP</category>
      <category>DIP</category>
    </item>
    <item>
      <title>The Liskov Substitution Principle for &amp;quot;Duck-Typed&amp;quot; Languages</title>
      <description>&lt;p&gt;&lt;span class="caps"&gt;OCP&lt;/span&gt; and &lt;span class="caps"&gt;LSP&lt;/span&gt; together tell us how to organize similar &lt;em&gt;vs.&lt;/em&gt; variant behaviors. I blogged the other day about &lt;a href="http://blog.objectmentor.com/articles/2008/09/04/the-open-closed-principle-for-languages-with-open-classes"&gt;&lt;span class="caps"&gt;OCP&lt;/span&gt; in the context of languages with open classes&lt;/a&gt;
 (&lt;em&gt;i.e.,&lt;/em&gt; dynamically-typed languages). Let&amp;#8217;s look at the &lt;a href="http://www.objectmentor.com/resources/articles/lsp.pdf"&gt;Liskov Substitution Principle&lt;/a&gt; (LSP).&lt;/p&gt;


	&lt;p&gt;The Liskov Substitution Principle was coined by Barbara Liskov in &lt;a href="http://portal.acm.org/citation.cfm?id=62141"&gt;Data Abstraction and Hierarchy&lt;/a&gt; (1987).&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I&amp;#8217;ve always liked the elegant simplicity, yet power, of &lt;span class="caps"&gt;LSP&lt;/span&gt;. In less formal terms, it says that if a client (program) expects objects of one type to behave in a certain way, then it&amp;#8217;s only okay to substitute objects of another type if the same expectations are satisfied.&lt;/p&gt;


	&lt;p&gt;This is our best definition of inheritance. The well-known &lt;strong&gt;is-a&lt;/strong&gt; relationship between types is not precise enough. Rather, the relationship has to be &lt;strong&gt;behaves-as-a&lt;/strong&gt;, which unfortunately is more of a mouthful. Note that &lt;strong&gt;is-a&lt;/strong&gt; focuses on the &lt;em&gt;structural&lt;/em&gt; relationship, while &lt;strong&gt;behaves-as-a&lt;/strong&gt; focuses on the &lt;em&gt;behavioral&lt;/em&gt; relationship. A very useful, pre-TDD design technique called &lt;a href="http://en.wikipedia.org/wiki/Design_by_contract"&gt;Design by Contract&lt;/a&gt; emerges out of &lt;span class="caps"&gt;LSP&lt;/span&gt;, but that&amp;#8217;s another topic.&lt;/p&gt;


	&lt;p&gt;Note that there is a slight assumption that I made in the previous paragraph. I said that &lt;span class="caps"&gt;LSP&lt;/span&gt; defines &lt;em&gt;inheritance&lt;/em&gt;. Why inheritance specifically and not &lt;em&gt;substitutability&lt;/em&gt;, in general? Well, inheritance has been the main vehicle for substitutability for most OO languages, especially the statically-typed ones.&lt;/p&gt;


	&lt;p&gt;For example, a Java application might use a simple tracing abstraction like this.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
public interface Tracing {
    void trace(String message);
}
    &lt;/code&gt;
&lt;/pre&gt;  

	&lt;p&gt;Clients might use this to trace methods calls to a log. Only classes that implement the &lt;code&gt;Tracer&lt;/code&gt; interface can be given to these clients. For example,&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
public class TracerClient {
    private Tracer tracer;

    public TracerClient(Tracer tracer) {
        this.tracer = tracer;
    }

    public void doWork() {
        tracer.trace("in doWork():");
        // ...
    }
}
    &lt;/code&gt;
&lt;/pre&gt;  

	&lt;p&gt;However, &lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;Duck Typing&lt;/a&gt; is another form of substitutability that is commonly seen in dynamically-typed languages, like Ruby and Python.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;If it walks like a duck and quacks like a duck, it must be a duck.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Informally, duck typing says that a client can use any object you give it as long as the object implements the methods the client wants to invoke on it. Put another way, the object must respond to the messages the client wants to send to it.&lt;/p&gt;


	&lt;p&gt;The object appears to be a &amp;#8220;duck&amp;#8221; as far as the client is concerned.&lt;/p&gt;


	&lt;p&gt;In or example, clients only care about the &lt;code&gt;trace(message)&lt;/code&gt; method being supported. So, we might do the following in Ruby.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
class TracerClient 
  def initialize tracer 
    @tracer = tracer
  end

  def do_work
    @tracer.trace "in do_work:" 
    # ... 
  end
end

class MyTracer
  def trace message
    p message
  end
end

client = TracerClient.new(MyTracer.new)
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;No &amp;#8220;interface&amp;#8221; is necessary. I just need to pass an object to &lt;code&gt;TracerClient.initialize&lt;/code&gt; that responds to the &lt;code&gt;trace&lt;/code&gt; message. Here, I defined a class for the purpose. You could also add the &lt;code&gt;trace&lt;/code&gt; method to another type or object.&lt;/p&gt;


	&lt;p&gt;So, &lt;span class="caps"&gt;LSP&lt;/span&gt; is still essential, in the generic sense of valid substitutability, but it doesn&amp;#8217;t have to be inheritance based.&lt;/p&gt;


	&lt;p&gt;Is Duck Typing good or bad? It largely comes down to your view about dynamically-typed &lt;em&gt;vs.&lt;/em&gt; statically-typed languages. I don&amp;#8217;t want to get into that debate here! However, I&amp;#8217;ll make a few remarks.&lt;/p&gt;


	&lt;p&gt;On the negative side, without a &lt;code&gt;Tracer&lt;/code&gt; abstraction, you have to rely on appropriate naming of objects to convey what they do (but you should be doing that anyway). Also, it&amp;#8217;s harder to find all the &amp;#8220;tracing-behaving&amp;#8221; objects in the system.&lt;/p&gt;


	&lt;p&gt;On the other hand, the client really doesn&amp;#8217;t care about a &amp;#8220;Tracer&amp;#8221; type, only a single method. So, we&amp;#8217;ve decoupled &amp;#8220;client&amp;#8221; and &amp;#8220;server&amp;#8221; just a bit more. This decoupling is more evident when using closures to express behavior, &lt;em&gt;e.g.,&lt;/em&gt; for &lt;code&gt;Enumerable&lt;/code&gt; methods. In our case, we could write the following.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
class TracerClient2 
  def initialize &amp;#38;tracer 
    @tracer = tracer
  end

  def do_work 
    @tracer.call "in do_work:" 
    # ... 
  end
end

client = TracerClient2.new {|message| p "block tracer: #{message}"}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;For comparison, consider how we might approach substitutability in &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. As a statically-typed language, Scala doesn&amp;#8217;t support duck typing &lt;em&gt;per se&lt;/em&gt;, but it does support a very similar mechanism called &lt;a href="http://neilbartlett.name/blog/2007/09/13/statically-checked-duck-typing-in-scala/"&gt;structural types&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Essentially, structural types let us declare that a method parameter must support one or more methods, without having to say it supports a full interface. Loosely speaking, it&amp;#8217;s like using an anonymous interface.&lt;/p&gt;


	&lt;p&gt;In our Java example, when we declare a tracer object in our client, we would be able to declare that is supports &lt;code&gt;trace&lt;/code&gt;, without having to specify that it implements a full interface.&lt;/p&gt;


	&lt;p&gt;To be explicit, recall our Java constructor for &lt;code&gt;TestClient&lt;/code&gt;.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
public class TracerClient {
    public TracerClient(Tracer tracer) { ... }
    // ...
    }
}
    &lt;/code&gt;
&lt;/pre&gt;  

In Scala, a complete example would be the following.
&lt;pre&gt;
    &lt;code&gt;
class ScalaTracerClient(val tracer: { def trace(message:String) }) {
    def doWork() = { tracer.trace("doWork") }
}

class ScalaTracer() {
    def trace(message: String) = { println("Scala: "+message) }
}

object TestScalaTracerClient {
    def main() {
        val client = new ScalaTracerClient(new ScalaTracer())
        client.doWork();
    }
}
TestScalaTracerClient.main()
    &lt;/code&gt;
&lt;/pre&gt;  

	&lt;p&gt;Recall from &lt;a href="http://blog.objectmentor.com/articles/2008/08/03/the-seductions-of-scala-part-i"&gt;my previous blogs on Scala&lt;/a&gt;, the argument list to the class name is the constructor arguments. The constructor takes a &lt;code&gt;tracer&lt;/code&gt; argument whose &amp;#8220;type&amp;#8221; (after the &amp;#8217;:&amp;#8217;) is &lt;code&gt;{ def trace(message:String) }&lt;/code&gt;. That is, all we require of &lt;code&gt;tracer&lt;/code&gt; is that it support the &lt;code&gt;trace&lt;/code&gt; method.&lt;/p&gt;


	&lt;p&gt;So, we get duck type-like behavior, but statically type checked. We&amp;#8217;ll get a compile error, rather than a run-time error, if someone passes an object to the client that doesn&amp;#8217;t respond to &lt;code&gt;tracer&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;To conclude, &lt;span class="caps"&gt;LSP&lt;/span&gt; can be reworded &lt;em&gt;very&lt;/em&gt; slightly.&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is &lt;strong&gt;substitutable for&lt;/strong&gt; T.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I replaced &lt;strong&gt;a subtype of&lt;/strong&gt; with &lt;strong&gt;substitutable for&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;An important point is that the idea of a &amp;#8220;contract&amp;#8221; between the types and their clients is still important, even in a  language with duck-typing or structural typing. However, languages with these features give us more ways to extend our system, while still supporting &lt;span class="caps"&gt;LSP&lt;/span&gt;.&lt;/p&gt;</description>
      <pubDate>Sat, 06 Sep 2008 23:48:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:48d425c0-b536-44de-bf6a-b83755c064b9</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2008/09/06/the-liskov-substitution-principle-for-duck-typed-languages</link>
      <category>Dean's Deprecations</category>
      <category>Dynamic Languages</category>
      <category>Design Principles</category>
      <category>Ruby</category>
      <category>ducktyping</category>
      <category>Scala</category>
      <category>Java</category>
      <category>design</category>
      <category>LSP</category>
    </item>
    <item>
      <title>Liskov Substitution Principle and the Ruby Core Libraries</title>
      <description>&lt;p&gt;There is a spirited discussion happening now on the ruby-talk list called &lt;a href="http://www.ruby-forum.com/topic/97965&lt;a href="""&gt;&amp;gt;Oppinions on &lt;span class="caps"&gt;RCR&lt;/span&gt; for dup on immutable classes&lt;/a&gt; (sic).&lt;/p&gt;


	&lt;p&gt;In the core Ruby classes, the &lt;code&gt;Kernel&lt;/code&gt; module, which is the root of everything, even &lt;code&gt;Object&lt;/code&gt;, defines a method called &lt;code&gt;dup&lt;/code&gt;, for duplicating objects. (There is also a &lt;code&gt;clone&lt;/code&gt; method with slightly different behavior that I won&amp;#8217;t discuss here.)&lt;/p&gt;


	&lt;p&gt;The problem is that some derived core classes throw an exception when &lt;code&gt;dup&lt;/code&gt; is called.&lt;/p&gt;


Specifically, as the ruby-talk discussion title says, it&amp;#8217;s the &lt;em&gt;immutable&lt;/em&gt; classes (&lt;code&gt;NilClass, FalseClass, TrueClass, Fixnum,&lt;/code&gt; and &lt;code&gt;Symbol&lt;/code&gt;) that do this. Consider, for example, the following &lt;strong&gt;irb&lt;/strong&gt; session: 
&lt;pre&gt;
irb 1:0&amp;gt; 5.respond_to? :dup
=&amp;gt; true
irb 2:0&amp;gt; 5.dup
TypeError: can't dup Fixnum
        from (irb):1:in `dup'
        from (irb):1
irb 3:0&amp;gt; 
&lt;/pre&gt;
If you don&amp;#8217;t know Ruby, the first line asks the &lt;code&gt;Fixnum&lt;/code&gt; object &lt;code&gt;5&lt;/code&gt; if it &lt;em&gt;responds to&lt;/em&gt; the method &lt;code&gt;dup&lt;/code&gt; (with the name expressed as a symbol, hence the&lt;/a&gt;). The answer is true, becuase this method is defined by the module &lt;code&gt;Kernel&lt;/code&gt;, which is included by the top-level class &lt;code&gt;Object&lt;/code&gt;, an ancestor of &lt;code&gt;Fixnum&lt;/code&gt;.

	&lt;p&gt;However, when you actually call &lt;code&gt;dup&lt;/code&gt; on &lt;code&gt;5&lt;/code&gt;, it raises &lt;code&gt;TypeError&lt;/code&gt;, as shown.&lt;/p&gt;


	&lt;p&gt;So, this looks like a classic &lt;a href="http://www.objectmentor.com/resources/articles/lsp.pdf"&gt;Liskov Substitution Principle&lt;/a&gt; violation. The term for this code smell is &lt;em&gt;Refused Bequest&lt;/em&gt; (&lt;em&gt;e.g.,&lt;/em&gt; see &lt;a href="http://www.soberit.hut.fi/mmantyla/BadCodeSmellsTaxonomy.htm"&gt;here&lt;/a&gt;) and it&amp;#8217;s typically fixed with the &lt;em&gt;refactoring&lt;/em&gt; &lt;a href="http://www.refactoring.com/catalog/replaceInheritanceWithDelegation.html"&gt;Replace Inheritance with Delegation&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The email thread is about a proposal to change the library in one of several possible ways. One possibility is to remove &lt;code&gt;dup&lt;/code&gt; from the &lt;em&gt;immutable&lt;/em&gt; classes. This would eliminate the unexpected behavior in the example above, since &lt;code&gt;5.respond_to?(:dup)&lt;/code&gt; would return false, but it would still be an &lt;span class="caps"&gt;LSP&lt;/span&gt; violation, specifically it would still have the &lt;em&gt;Refused Bequest&lt;/em&gt; smell.&lt;/p&gt;


	&lt;p&gt;One scenario where the current behavior causes problems is doing a deep copy of an arbitrary object graph. For immutable objects, you would normally just want &lt;code&gt;dup&lt;/code&gt; to return the same object. It&amp;#8217;s immutable, right? Well, not exactly, since you can re-open classes and even objects to add and remove methods in Ruby (there are some limitations for the immutables&amp;#8230;).  So, if you thought you actually duplicated something and started messing with its methods, you would be surprised to find the original was &amp;#8220;also&amp;#8221; modified.&lt;/p&gt;


	&lt;p&gt;So, how serious is this &lt;span class="caps"&gt;LSP&lt;/span&gt; issue (one of several)? When I pointed out the problem in the discussion, one respondent, Robert Dober, said the following (edited slightly):&lt;/p&gt;


	&lt;p&gt;&lt;i&gt;
I would say that &lt;span class="caps"&gt;LSP&lt;/span&gt; does not apply here simply because in Ruby we do
not have that kind of contract. In order to apply &lt;span class="caps"&gt;LSP&lt;/span&gt; we need to say at a point we have an object of class &lt;code&gt;Base&lt;/code&gt;, for example. (let the gods forgive me that I use Java)&lt;/i&gt;
&lt;pre&gt;
void aMethod(final Base b){
   ....
}
&lt;/pre&gt;
&lt;i&gt;and we expect this to work whenever we call aMethod with an object
that is a Base.
Anyway the compiler would not really allow otherwise.&lt;/i&gt;
&lt;pre&gt;
SubClass sc;  // subclassing Base od course
aMethod( sc ); // this is expected to work (from the type POV).
&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;&lt;i&gt;Such things just do not exist in Ruby, I believe that Ruby has
explained something to me:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;OO Languages are Class oriented languages&lt;/li&gt;
		&lt;li&gt;Dynamic Languages are Object oriented languages.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Replace Class with Type and you see what I mean.&lt;/p&gt;


	&lt;p&gt;This is all very much &lt;span class="caps"&gt;IMHO&lt;/span&gt; of course but I feel that the Ruby
community has made me evolve a lot away from &amp;#8220;Class oriented&amp;#8221;.&lt;/i&gt;&lt;/p&gt;


	&lt;p&gt;He&amp;#8217;s wrong that the compiler protects you in Java; you can still throw exceptions, &lt;em&gt;etc.&lt;/em&gt; The &lt;span class="caps"&gt;JDK&lt;/span&gt; Collection classes have &lt;em&gt;Refused Bequests&lt;/em&gt;. Besides that, however, he makes some interesting points.&lt;/p&gt;


	&lt;p&gt;As a long-time Java programmer, I&amp;#8217;m instinctively uncomfortable with &lt;span class="caps"&gt;LSP&lt;/span&gt; violations. Yet, the Ruby &lt;span class="caps"&gt;API&lt;/span&gt; is very nice to work with, so maybe a little &lt;span class="caps"&gt;LSP&lt;/span&gt; violation isn&amp;#8217;t so bad?&lt;/p&gt;


	&lt;p&gt;As Robert says, we approach our designs differently in dynamic &lt;em&gt;vs.&lt;/em&gt; static languages. In Ruby, you almost never use the &lt;code&gt;is_a?&lt;/code&gt; and &lt;code&gt;kind_of?&lt;/code&gt; methods to check for type. Instead, you follow the &lt;em&gt;duck typing&lt;/em&gt; philosophy (&amp;#8220;If it acts like a duck, it must be a duck&amp;#8221;); you rely on &lt;code&gt;respond_to?&lt;/code&gt; to decide if an object does what you want.&lt;/p&gt;


	&lt;p&gt;In the case of &lt;code&gt;dup&lt;/code&gt; for the immutable classes, I would prefer that they not implement the method, rather than throw an exception. However, that would still violate &lt;span class="caps"&gt;LSP&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;So, can we still satisfy &lt;span class="caps"&gt;LSP&lt;/span&gt; and also have rich base classes and modules?&lt;/p&gt;


	&lt;p&gt;There are many examples of &lt;em&gt;traits&lt;/em&gt; that one object might or should support, but not another. (Those of you Java programmers might ask yourself why all objects support &lt;code&gt;toString&lt;/code&gt;, for example. Why not also &lt;code&gt;toXML&lt;/code&gt;...?)&lt;/p&gt;


	&lt;p&gt;Coming from an &lt;a href="http://aspectprogramming.com"&gt;&lt;span class="caps"&gt;AOP&lt;/span&gt;&lt;/a&gt; background, I would rather see an architecture where &lt;code&gt;dup&lt;/code&gt; is added only to those classes and modules that can support it. It shouldn&amp;#8217;t be part of the standard &amp;#8220;signature&amp;#8221; of &lt;code&gt;Kernel&lt;/code&gt;, but it should be present when code actually needs it.&lt;/p&gt;


In fact, Ruby makes this sort of &lt;span class="caps"&gt;AOP&lt;/span&gt; &lt;a href="c2.com/cgi/wiki?AspectsAndDynamicLanguages"&gt;easy&lt;/a&gt; to implement. Maybe &lt;code&gt;Kernel&lt;/code&gt;, &lt;code&gt;Module&lt;/code&gt;, and &lt;code&gt;Object&lt;/code&gt; should be refactored into smaller pieces and programmers should declaratively mixin the &lt;em&gt;traits&lt;/em&gt; they need. Imagine something like the following:
&lt;pre&gt;
irb 1:0&amp;gt; my_obj.respond_to? :dup
=&amp;gt; false
irb 2:0&amp;gt; include 'DupableTrait'  
irb 2:0&amp;gt; my_obj.respond_to? :dup
=&amp;gt; true
irb 4:0&amp;gt; def dup_if_possible items
irb 5:1&amp;gt;  items.map {|item| item.respond_to?(:dup) ? item.dup : item}
irb 6:1&amp;gt; end
...
&lt;/pre&gt;
In other words, &lt;code&gt;Kernel&lt;/code&gt; no longer &amp;#8220;exposes the &lt;code&gt;dup&lt;/code&gt; abstraction&amp;#8221;, by default, but the &lt;code&gt;DupableTrait&lt;/code&gt; module &amp;#8220;magically&amp;#8221; adds &lt;code&gt;dup&lt;/code&gt; to all the classes that can support it. This way, we preserve &lt;span class="caps"&gt;LSP&lt;/span&gt;, streamline the core classes and modules (&lt;a href="http://www.objectmentor.com/resources/articles/srp"&gt;&lt;span class="caps"&gt;SRP&lt;/span&gt;&lt;/a&gt; and &lt;a href="http://www.objectmentor.com/resources/articles/isp.pdf"&gt;&lt;span class="caps"&gt;ISP&lt;/span&gt;&lt;/a&gt; anyone?), yet we have the flexibility we need, on demand.</description>
      <pubDate>Sat, 17 Feb 2007 14:20:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:767b95e8-95d2-45dd-8aa0-09dfb4fe92ec</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2007/02/17/liskov-substitution-principle-and-the-ruby-core-libraries</link>
      <category>Dean's Deprecations</category>
      <category>Dynamic Languages</category>
      <category>Design Principles</category>
      <category>Ruby</category>
      <category>object-oriented design</category>
      <category>Liskov Substitution Principle</category>
      <category>LSP</category>
      <trackback:ping>http://blog.objectmentor.com/articles/trackback/188</trackback:ping>
    </item>
  </channel>
</rss>

