ocaml — Как выводить PHP-функции с необязательными аргументами

Суть PHP в том, что он не имеет определенного синтаксиса при использовании функции с необязательными аргументами. Это:

foo(10);

может быть это

function foo($a) {}

или это

function foo($a = 0) {}

или это

function foo($a, $b = 0, ...) {}

(или даже function foo() {}, но не обращайте на это внимания сейчас).

Итак, как мы можем вывести его, когда функция используется до ее определения?

Одно из решений состоит в том, чтобы записать все случаи использования, пока не придет определение, а затем посмотреть, смогут ли они все объединиться с ним. Приведенный выше пример будет хранить

int -> unit

и позже проверьте, совместимо ли это с

int -> (typ list) -> unit

или что угодно (где typ list список необязательных аргументов).

Вы думаете, это может сработать? Существуют ли другие традиционные способы борьбы с этим?

1

Решение

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

0

Другие решения

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

Конкретно я думаю ReflectionFunction а также ReflectionParameter может быть полезным в вашем случае, хотя есть гораздо больше функций, которые могут помочь.

Например, вот очень простой пример, где вы хотите получить некоторую информацию об аргументах функции:

<?php

// a simple function with an
// optional/default argument
function foo($a, $b = 0)
{
return $a + $b;
}

// create a ReflectionFunction object
// passing the name of the function name.
// you can also pass a variable reference
// to an anonymous function.
$refl = new ReflectionFunction('foo');

// iterate over the ReflectionFunction's
// parameter list to get a ReflectionParameter
// object for each of foo's arguments. here we're
// just printing out a __toString() summary of each
// argument.
foreach ($refl->getParameters() as $param) {
echo $param . PHP_EOL;
}

Урожайность:

Parameter #0 [ <required> $a ]
Parameter #1 [ <optional> $b = 0 ]

Как видите, этот простой пример показывает некоторую информацию о fooСписок аргументов: номер параметра, обязательный / необязательный, имя переменной и значение по умолчанию.

$param это пример ReflectionParameter поэтому есть несколько методов, которые вы можете вызвать для получения дополнительной информации о каждом аргументе, включая:

export
__construct
__toString
getName
isPassedByReference
canBePassedByValue
getDeclaringFunction
getDeclaringClass
getClass
isArray
isCallable
allowsNull
getPosition
isOptional
isDefaultValueAvailable
getDefaultValue
isDefaultValueConstant
getDefaultValueConstantName

Надеюсь это поможет! 🙂

0

По вопросам рекламы [email protected]