2010-06-10 7 views
10

ExplicaciónCódigo-Golf: una línea de sintaxis PHP

PHP tiene algunos agujeros en su sintaxis y de vez en cuando en el desarrollo de un programador va a intensificar en ellos. Esto puede llevar a mucha frustración ya que estos agujeros de sintaxis parecen existir sin ningún motivo. Por ejemplo, uno no puede crear fácilmente una matriz y acceder a un elemento arbitrario de esa matriz en la misma línea (func1()[100] no es una sintaxis PHP válida). La solución para este problema es utilizar una variable temporal y dividir la instrucción en dos líneas, pero a veces eso puede llevar a un código muy detallado y poco claro.

Desafío

Sé de algunos de estos agujeros (estoy seguro de que hay más). Es bastante difícil incluso encontrar una solución, y mucho menos en un estilo de código de golf. El ganador es la persona con el menor total de caracteres para los cuatro espacios de sintaxis.

Reglas

  1. Declaración debe ser una línea del siguiente modo: $output = ...;, donde ... no contiene ningún ; 's.
  2. Utilice únicamente las funciones estándar de la biblioteca (no hay funciones personalizadas o eval permitidos)
  3. comando funciona de forma idéntica a la funcionalidad supuesta de la sintaxis que no funciona (incluso en los casos en que se produce un error).
  4. La instrucción debe ejecutarse sin ningún error de sintaxis de ningún tipo con E_STRICT | E_ALL.

Agujeros de sintaxis

  1. $output = func_return_array()[$key]; - acceder a un desplazamiento arbitrario (string o integer) de la matriz devuelta de una función
  2. $output = new {$class_base.$class_suffix}(); - arbitraria concatenación de cadenas que se utilizan para crear una nueva clase
  3. $output = {$func_base.$func_suffix}(); - se llama a la concatenación de cadenas arbitraria como función
  4. $output = func_return_closure()(); - llamar a un cierre que se devuelven desde otra función
+0

matriz de eliminación de referencias (el agujero de sintaxis 1.) ya ha sido confirmado en el tronco por Felipe Peña. – Artefacto

+0

@Artefacto ¡Son noticias increíbles! Los últimos susurros que escuché fueron que fue ignorado. ¿Tienes un enlace para eso? –

+2

Creo que este ejercicio no tiene sentido. Menos caracteres es diferente de más claro/más eficiente. – Artefacto

Respuesta

8

La única solución que veo implica una variable temporal, por lo que no es cierta (mínimo) la contaminación del espacio de nombres. Cualquier forma de apretar el código variable temporal acortaría los 4 de los siguientes:

<?php 

error_reporting(E_ALL | E_STRICT); 

// 1 
function func_return_array() { return array(0 => 'hello'); } 
$key = 0; 

$output = ${!${''}=func_return_array()}[$key]; 

echo '1: ' . $output . "\n"; 


// 2 
class Thing {} 
$class_base = 'Thi'; $class_suffix = 'ng'; 

$output = new ${!${''}=$class_base.$class_suffix}(); 

echo '2: '; 
var_dump($output); 


// 3 
$func_base = 'func_'; $func_suffix = 'return_array'; 

$output = ${!${''}=$func_base.$func_suffix}(); 

echo '3: '; 
var_dump($output); 


// 4 
function func_return_closure() { 
    return function() { 
     return 'This is a closure'; 
    }; 
} 

$output = ${!${''}=func_return_closure()}(); 

echo '4: '; 
var_dump($output); 

Salida:

1: hello 
2: object(Thing)#1 (0) { 
} 
3: array(1) { 
    [0]=> 
    string(5) "hello" 
} 
4: string(17) "This is a closure" 
+1

Es muy interesante cómo puedes hacer una asignación de variables de esa manera. Nunca he visto esa sintaxis antes. –

2

Mi solución es ligeramente más largo que Shauns', pero yo pensé en tirar hacia arriba de todos modos. Debería funcionar de forma idéntica a la sintaxis original, incluso en casos de error. Básicamente estoy explotando la sintaxis ternaria para permitir dos líneas en una. También cambié la variable temporal a ${0} en lugar de ${''} ya que guarda un carácter y las variables que comienzan con números no son válidas.

Las declaraciones de abajo,

line1; 
$output = line2; 

es idéntica a la siguiente declaración para todos los casos posibles.

$output = (line1)&&0?:(line2); 

Mi solución:

<?php 

error_reporting(E_ALL | E_STRICT); 

// 1 
function func_return_array() { return array(0 => 'hello'); } 
$key = 0; 

$output = (${0}=func_return_array())&&0?:${0}[$key]; 

echo '1: ' . $output . "\n"; 


// 2 
class Thing {} 
$class_base = 'Thi'; $class_suffix = 'ng'; 

$output = (${0}=$class_base.$class_suffix)&&0?:new ${0}; 

echo '2: '; 
var_dump($output); 


// 3 
$func_base = 'func_'; $func_suffix = 'return_array'; 

$output = (${0}=$func_base.$func_suffix)&&0?:${0}(); 

echo '3: '; 
var_dump($output); 


// 4 
function func_return_closure() { 
    return function() { 
     return 'This is a closure'; 
    }; 
} 

$output = call_user_func(func_return_closure()); //more straight forward 
//$output = (${0}=func_return_closure())&&0?:${0}(); 
echo '4: '; 
var_dump($output); 

?>