title: Why doesn't lapply work on S4 objects which have an as.list.default method?
body: <p>Suppose I have a vector-like S4 class:</p>
  
  <pre><code>.MyClass &lt;- setClass("MyClass", representation(a="numeric", b="character"))
  
  setMethod("[", c("MyClass", "numeric", "missing"), function(x, i, j, ...) {
    do.call(initialize, c(x, sapply(slotNames(x), function(y) slot(x, y)[i],
            simplify=FALSE)))
  })
  
  setMethod("length", "MyClass", function(x) length(x@a))
  </code></pre>
  
  <p>And say I have also defined methods for <code>as.list</code> and <code>as.list.default</code>:</p>
  
  <pre><code>setGeneric("as.list")
  setMethod("as.list", "MyClass",
            function(x) lapply(seq_along(x), function(i) x[i]))
  setGeneric("as.list.default")
  setMethod("as.list.default", "MyClass",
            function(x) lapply(seq_along(x), function(i) x[i]))
  </code></pre>
  
  <p>Now given an object of this class, <code>myobj</code>:</p>
  
  <pre><code>myobj &lt;- .MyClass(a=1:4, b=letters[1:4])
  </code></pre>
  
  <p>When I use <code>lapply</code>, it complains:</p>
  
  <pre><code>&gt; lapply(myobj, function(i) rep(i@b, i@a))
  Error in as.list.default(X) : 
    no method for coercing this S4 class to a vector
  </code></pre>
  
  <p>But if I use <code>as.list.default</code>, the function gives the desired output:</p>
  
  <pre><code>&gt; lapply(as.list.default(myobj), function(i) rep(i@b, i@a))
  [[1]]
  [1] "a"
  
  [[2]]
  [1] "b" "b"
  ...
  </code></pre>
  
  <p>Why does <code>lapply</code> not work even though I have defined a method for <code>as.list.default</code> for the class?</p>
  
  <p>Obviously I can manually define a <code>lapply</code> method for the class and it will work fine (below), but I was wondering where the error is actually being encountered. Why is <code>lapply</code> attempting to coerce my object into a vector even though the function it is calling should be turning the object into a list?</p>
  
  <pre><code>setGeneric("lapply")
  setMethod("lapply", c("MyClass", "function"), function(X, FUN, ...) {
    lapply(as.list(X), FUN, ...)
  })
  lapply(myobj, function(i) rep(i@b, i@a))
  </code></pre>