2010-06-10 4 views
10

Explicationcode-Golf: une ligne PHP syntaxe

PHP a quelques trous dans sa syntaxe et de temps en temps dans le développement d'un programmeur étape en eux. Cela peut conduire à beaucoup de frustration car ces trous de syntaxe semblent exister sans raison. Par exemple, on ne peut pas facilement créer un tableau et accéder à un élément arbitraire de ce tableau sur la même ligne (func1()[100] n'est pas une syntaxe PHP valide). La solution de contournement pour ce problème consiste à utiliser une variable temporaire et à diviser l'instruction en deux lignes, mais parfois cela peut conduire à un code très verbeux et maladroit.

Défi

Je connais quelques-unes de ces trous (je suis sûr qu'il ya plus). Il est assez difficile de trouver une solution, encore moins dans un style de code-golf. Le gagnant est la personne avec au moins le total des caractères pour les quatre trous de syntaxe.

Règles

  1. Déclaration doit être une ligne sous cette forme: $output = ...;, où ... ne contient pas de ; « s.
  2. Utilisez uniquement les fonctions de bibliothèque standard (aucune fonction personnalisée ou eval autorisé)
  3. L'instruction fonctionne de manière identique à la fonction supposée de la syntaxe non fonctionnelle (même en cas d'échec).
  4. L'instruction doit s'exécuter sans erreur de syntaxe de quelque sorte que ce soit avec E_STRICT | E_ALL.

trous de syntaxe

  1. $output = func_return_array()[$key]; - accéder à un décalage arbitraire (string ou integer) du réseau de retour d'une fonction
  2. $output = new {$class_base.$class_suffix}(); - concaténation de chaînes arbitraires utilisées pour créer une nouvelle classe
  3. $output = {$func_base.$func_suffix}(); - concaténation de chaîne arbitraire appelée comme fonction
  4. $output = func_return_closure()(); - appeler une fermeture étant retourné d'une autre fonction
+0

Tableau déréférencement (votre 1. trou de syntaxe) a déjà été engagée à tronc par Felipe Pena. – Artefacto

+0

@Artefacto C'est une excellente nouvelle! Les derniers chuchotements que j'ai entendus ont été ignorés. Avez-vous un lien pour cela? –

+2

Je pense que cet exercice est inutile. Moins de caractères est différent de plus clair/plus efficace. – Artefacto

Répondre

8

La seule solution que je vois implique une variable temporaire, donc il y a une certaine pollution de l'espace de noms (minimum). De toute façon de resserrer le code variable temporaire raccourcirait les 4 de ces derniers:

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

Sortie:

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

Il est très intéressant de savoir comment vous pouvez faire une assignation de variable de cette façon. Jamais vu cette syntaxe avant. –

2

Ma solution est un peu plus longue que Shauns mais je pensais que je jetterais vers le haut de toute façon. Il devrait fonctionner de manière identique à la syntaxe d'origine, même dans les cas d'erreur. J'utilise essentiellement la syntaxe ternaire pour permettre deux lignes en une. J'ai également changé la variable temporaire à ${0} au lieu de ${''} puisqu'il enregistre un caractère et les variables qui commencent par des nombres ne sont pas valides.

Les énoncés ci-dessous,

line1; 
$output = line2; 

est identique à la déclaration suivante pour tous les cas possibles.

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

Ma solution:

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

?>