do and {} to denote blocks attached to methods are not completely interchangeable.
p test do
1
end
Precedence is screwing with you. This is actually this:
p(test()) do
1
end
So the block is getting passed to p, not test.
{} has higher precedence than do, and so binds more tightly to the syntactically closer method. This is also true for other ruby keywords that have symbolic equivalents, such as and/&& and or/||, which is why the symbols are usually recommended over the words.