Это разница между procs vs lambdas (поиск в Google, который даст вам больше ресурсов).
По сути, в первом случае ваш "return foo1" возвращает из лаборатории и должен находиться внутри контекста, куда возвращаться.
Вы можете добиться того, что пытаетесь сделать, используя лямбду
p = lambda { return "from block" }
Также обратите внимание, что вам обычно не нужны операторы return
ни в процедурах, ни в лямбдах; они вернут последнее оцененное выражение. Итак, это эквивалентно:
p = Proc.new{ "from block" }