2010-06-10 9 views
10

SpiegazioneCodice-Golf: una riga di sintassi di PHP

PHP ha alcuni buchi nella sua sintassi e di tanto in tanto in fase di sviluppo un programmatore farà un passo in loro. Ciò può causare molta frustrazione dato che questi buchi di sintassi sembrano esistere senza motivo. Ad esempio, non è possibile creare facilmente una matrice e accedere a un elemento arbitrario di tale matrice sulla stessa riga (func1()[100] non è una sintassi PHP valida). La soluzione alternativa a questo problema consiste nell'utilizzare una variabile temporanea e suddividere l'istruzione in due righe, ma a volte può portare a un codice molto prolisso e prolisso.

Sfida

So di alcuni di questi fori (sono sicuro che ci sono più). È abbastanza difficile persino trovare una soluzione, figuriamoci in uno stile di codice-golf. Il vincitore è la persona con almeno i caratteri totali per tutti e quattro i fori di sintassi.

Regole

  1. dichiarazione deve essere una riga in questa forma: $output = ...;, dove ... non contiene alcun ; 's.
  2. Utilizzare solo le funzioni di libreria standard (nessuna funzione personalizzata o eval consentita)
  3. L'istruzione funziona in modo identico al funzionamento ipotizzato della sintassi non funzionante (anche nei casi in cui non riesce).
  4. L'istruzione deve essere eseguita senza errori di sintassi di alcun tipo con E_STRICT | E_ALL.

fori sintassi

  1. $output = func_return_array()[$key]; - accedendo un offset arbitrario (string o integer) dell'array restituito di una funzione
  2. $output = new {$class_base.$class_suffix}(); - arbitraria concatenazione stringa utilizzati per creare una nuova classe
  3. $output = {$func_base.$func_suffix}(); - concatenazione di stringa arbitraria chiamata come funzione
  4. $output = func_return_closure()(); - consultare chiusura essendo tornati da un'altra funzione
+0

Array dereferenziazione (il vostro 1. Foro sintassi) è già stata impegnata a tronco da Felipe Pena. – Artefacto

+0

@Artefacto Questa è una notizia fantastica! Gli ultimi sussurri che ho sentito sono stati ignorati. Hai un link per questo? –

+2

Penso che questo esercizio sia inutile. Meno caratteri è diverso da più chiaro/più efficiente. – Artefacto

risposta

8

L'unica soluzione che vedo comporta una variabile temporanea, per cui v'è una certa (minima) inquinamento namespace. Qualsiasi modo di stringere il codice variabile temporanea sarebbe accorciare tutti e 4 di questi:

<?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); 

uscita:

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

È molto interessante come sia possibile eseguire un compito variabile in questo modo. Non ho mai visto prima quella sintassi. –

2

La mia soluzione è leggermente più lungo Shauns', ma ho pensato di butto comunque. Dovrebbe funzionare in modo identico alla sintassi originale, anche in casi di errore. Sto praticamente sfruttando la sintassi ternaria per consentire due linee in una. Ho anche modificato la variabile temporanea su ${0} anziché su ${''} poiché salva un carattere e le variabili che iniziano con i numeri non sono valide.

Le seguenti affermazioni,

line1; 
$output = line2; 

è identico a quello seguente dichiarazione per tutti i casi possibili.

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

La mia soluzione:

<?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); 

?> 
Problemi correlati