3

I used Extract with Hold to retrieve a sublist containing expressions I didn't want evaluating, e.g.

foo = Extract[OwnValues[test], {1, 2}, Hold]
(* Hold[{expr1, expr2, expr3}] *)

I'm sorry to ask such a trivial question, but, how do I get the length of that list?

Obviously Length@foo returns 1 because the top-level head is Hold. But attempting to access the lower levels seems to cause evaluation one way or another. What technique am I missing?

Andrew Cheong
  • 3,576
  • 17
  • 42
  • Use Unevaluated instead of Hold or obtain expression where each list entry is wrapped in Hold. – Wizard Feb 27 '14 at 06:51

1 Answers1

3
test = Hold[{Print@2; 1, 2, 3}];

One of many ways would be

test /. Hold[l_List] :> Length@Unevaluated@l

A couple others

Function[l, Length@Unevaluated@l, HoldAll] @@ test
test /. Hold[{args___}] :> Length@Hold[args]
Rojo
  • 42,601
  • 7
  • 96
  • 188
  • Ah, I see. As @Wizard was saying, I was trying to use Unevaluated, but my attempts would evaluate too little. Substitution's what I needed. Thanks! – Andrew Cheong Feb 27 '14 at 07:54
  • 1
    @acheong87, if you'll do it more than once, you could create a function using your own idea of Extract, such as lengthAt[expr_, pos_] := Extract[expr, pos, Function[l, Length@Unevaluated@l, HoldAll]]. Then, lengthAt[test, 1] – Rojo Feb 27 '14 at 07:57