Вызов функций в аргументах функций

Продолжаем тему выражений. Как вы помните, вызов функции — выражение, а значит мы можем положить вызов функции в вызов функции (…в вызов функции в вызов функции в вызов… а-а-а!).

<?php

$number = 100.234203;
$result = round(abs($number), 2);

Мы вызываем функцию round и передаем ей два аргумента:

  • результат вызова функции abs с аргументом $number
  • число 2.

Можно сделать то же самое, но с промежуточными шагами:

<?php

$number = 100.234203;
$module = abs($number);

$result = round($module, 2);

Какой вариант предпочтительнее? Если вычисление совсем простое и не глубокое (не больше одного вложения функции), то можно смело вкладывать вызов в вызов. В остальных ситуациях предпочтительно разбивать вызовы на промежуточные вычисления.

Причины все те же. Чтение такого кода значительно легче. Во-первых, промежуточные переменные своими названиями отражают суть операций. Во-вторых, такой код легче отлаживать, а промежуточные данные проще исследовать. И в-третьих, глубокие вложенные вызовы сложно читать. В продвинутых языках подобная проблема решается механизмом типа композиции функций, но в PHP, к сожалению, подобного нет.

Давайте вглянем на код и попробуем ответить на вопрос: что в каком порядке будет вычисляться?

<?php

$number = -100.234203;
$result = round(abs($number), round(2.43));

PHP, как и большинство традиционных языков, является языком с жадными вычислениями (в других языках бывают ленивые вычисления). PHP пытается вычислить сначала максимально глубокий уровень вызова, затем менее глубокий, и так двигается снизу вверх пока не вычислит всё.

В нашем примере сначала будут вычислены аргументы, а затем получившиеся данные попадут в вызов round.

Ситуация с вложенными вызовами функций часто вводит новичков в ступор. Здесь нет никакой магии, нужно просто чуть больше тренировок. Хорошее упражнение — расписывать процесс по шагам на бумажке, симулируя действия компьютера. Вот так:

  1. $result = round(abs($number), round(2.43));
  2. $result = round(100.234203, round(2.43));
  3. $result = round(100.234203, 2);
  4. $result = 100.23;

Задание

Для построения генеалогического дерева семьи Старков Сэм написал функцию parentFor, которая возвращает имя родителя, если передать ей первым параметром имя ребенка. Вторым параметром функция принимает строчку father или mother. Так функция понимает, кого из родителей возвращать. По умолчанию параметр равен mother. То есть, если нужно узнать имя матери, то можно не передавать специально mother, а передать лишь один параметр — имя ребенка.

Напишите программу, которая выводит на экран имя деда Джоффри по материнской линии. Полное имя Джоффри на английском: Joffrey Baratheon.

Упражнение доступно только авторизованным пользователям.

Пожалуйста, авторизуйтесь с помощью учётной записи GitHub, это необходимо для отслеживания прогресса выполнения уроков. Если у вас ещё нет учётной записи, то сейчас самое время создать аккаунт на GitHub.