Я думаю, вы можете быть озадачены функциональностью вызова module_function, так как этот метод фактически создает копию метода и делает исходный метод частным, и смешивает копию с мета-классом (или собственным классом в любом случай на один шаг вверх по цепочке поиска метода). Это так, что его можно переопределить, не влияя на внутреннее использование метода, то есть сделать его безопасным для частного использования, а также быть общедоступным ИЛИ общедоступным. Только копия, которая смешана с мета-классом, не может получить доступ к aa, и это потому, что aa не существует над ним в цепочке поиска. Если оба метода были переданы в функцию модуля, вы не получите неопределенную ошибку метода.