Необходимо взглянуть на Повышение. Python . Вот краткое введение, взятое от их веб-сайта:
Повышение Библиотека Python является платформой для взаимодействия через интерфейс с Python и C++. Это позволяет Вам быстро, и беспрепятственно представьте функции классов C++ и объекты к Python, и наоборот, не используя специальных инструментов - просто Ваш компилятор C++. Это разработано для обертывания интерфейсов C++ ненавязчиво, так, чтобы Вы не изменяли код C++ вообще для обертывания его, делая Повышение. Идеал Python для представления сторонних библиотек к Python. Использование библиотекой усовершенствованных методов метапрограммирования упрощает свой синтаксис для пользователей, так, чтобы обертывание кода взяло вид своего рода декларативного языка определения интерфейсов (IDL).
У меня действительно есть подходящий вариант использования для этого.
У меня есть функция cacheVariable ($ var) (хорошо, у меня есть кеш функций ($ key, $ value), но я я хотел бы иметь функцию, как упомянуто).
Цель состоит в следующем:
$colour = 'blue';
cacheVariable($colour);
...
// another session
...
$myColour = getCachedVariable('colour');
Я пробовал с
function cacheVariable($variable) {
$key = ${$variable}; // This doesn't help! It only gives 'variable'.
// do some caching using suitable backend such as apc, memcache or ramdisk
}
Я также пробовал с
function varName(&$var) {
$definedVariables = get_defined_vars();
$copyOfDefinedVariables = array();
foreach ($definedVariables as $variable=>$value) {
$copyOfDefinedVariables[$variable] = $value;
}
$oldVar = $var;
$var = !$var;
$difference = array_diff_assoc($definedVariables, $copyOfDefinedVariables);
$var = $oldVar;
return key(array_slice($difference, 0, 1, true));
}
Но это тоже не удается ...: (
Конечно, я мог бы продолжать делать cache ('color', $ color), но я ленив, понимаете ...;)
Итак, что я want - это функция, которая получает ОРИГИНАЛЬНОЕ имя переменной, как оно было передано функции. Внутри функции я никак не могу это знать, как кажется. Передача get_defined_vars () по ссылке во втором примере выше мне несколько помогла (спасибо Жан-Жаку Гегану за эту идею). Последняя функция начала работать, но по-прежнему возвращала только локальную переменную (' переменная ', а не' цвет ').
Я еще не пробовал использовать вместе конструкции get_func_args () и get_func_arg (), $ {} и key (), но предполагаю, что это тоже не сработает.
Я сделал функцию проверки для отладки. Это похоже на print_r () на стероидах, очень похоже на Крумо, но немного более эффективно для объектов. Я хотел добавить определение имени переменной и сделал это, вдохновленный публикацией Ника Престы на этой странице. Он обнаруживает любое выражение, переданное в качестве аргумента, а не только имена переменных.
Это только функция-оболочка, которая обнаруживает переданное выражение. Работает в большинстве случаев. Это не сработает, если вы вызовете функцию более одного раза в одной строке кода.
Это отлично работает: die ( inspect ( $ this-> getUser () -> hasCredential ("delete") ) );
inspect () - это функция, которая обнаружит переданное выражение.
Получаем: $ this-> getUser () -> hasCredential ("delete")
function inspect($label, $value = "__undefin_e_d__")
{
if($value == "__undefin_e_d__") {
/* The first argument is not the label but the
variable to inspect itself, so we need a label.
Let's try to find out it's name by peeking at
the source code.
*/
/* The reason for using an exotic string like
"__undefin_e_d__" instead of NULL here is that
inspected variables can also be NULL and I want
to inspect them anyway.
*/
$value = $label;
$bt = debug_backtrace();
$src = file($bt[0]["file"]);
$line = $src[ $bt[0]['line'] - 1 ];
// let's match the function call and the last closing bracket
preg_match( "#inspect\((.+)\)#", $line, $match );
/* let's count brackets to see how many of them actually belongs
to the var name
Eg: die(inspect($this->getUser()->hasCredential("delete")));
We want: $this->getUser()->hasCredential("delete")
*/
$max = strlen($match[1]);
$varname = "";
$c = 0;
for($i = 0; $i < $max; $i++){
if( $match[1]{$i} == "(" ) $c++;
elseif( $match[1]{$i} == ")" ) $c--;
if($c < 0) break;
$varname .= $match[1]{$i};
}
$label = $varname;
}
// $label now holds the name of the passed variable ($ included)
// Eg: inspect($hello)
// => $label = "$hello"
// or the whole expression evaluated
// Eg: inspect($this->getUser()->hasCredential("delete"))
// => $label = "$this->getUser()->hasCredential(\"delete\")"
// now the actual function call to the inspector method,
// passing the var name as the label:
// return dInspect::dump($label, $val);
// UPDATE: I commented this line because people got confused about
// the dInspect class, wich has nothing to do with the issue here.
echo("The label is: ".$label);
echo("The value is: ".$value);
}
Вот пример функции инспектора (и моего класса dInspect) в действии:
Тексты на этой странице написаны на испанском языке, но код краток и действительно прост для понимания.
У меня есть это:
debug_echo(array('$query'=>$query, '$nrUsers'=>$nrUsers, '$hdr'=>$hdr));
Я бы предпочел следующее:
debug_echo($query, $nrUsers, $hdr);
Существующая функция отображает желтое поле с красным контуром и показывает каждую переменную по имени и значению. Решение с массивом работает, но при необходимости его вводить немного запутанно.
Это мой вариант использования, и да, он действительно связан с отладкой. Я согласен с теми, кто сомневается в его использовании в противном случае.