Ваша проблема не имеет ничего общего с замыканиями или блоками. Это связано с тем, как обрабатываются операторы в Ruby.
В бинарных операциях, таких как *
и +
, , объект слева от операнда является получателем метода . Поэтому, когда вы делаете "hello " * 3
, он вызывает метод *
для класса String
и передает 3
в качестве параметра. Определение String#*
принимает целые числа в качестве параметров и возвращает self
, повторенное столько раз, следовательно, вывод "hello hello hello "
.
Но если вы сформулируете его как 3 * "hello "
, вызывается метод *
класса Fixnum
, и "hello "
передается в качестве параметра. Fixnum#*
не знает, что делать с параметрами String
, поэтому вы получаете сообщение об ошибке.