2010-06-10 12 views
10

AçıklamaKod-Golf: bir satır PHP sözdizimi

PHP onun sözdiziminde bazı delikler vardır ve bazen gelişiminde programcı onlarda adım olacaktır. Bu sözdizimi delikleri hiçbir sebepten yoksun gibi göründüğü için çok fazla hayal kırıklığına yol açabilir. Örneğin, bir dizi kolayca bir dizi oluşturamaz ve aynı dizide bu dizinin rasgele bir öğeye erişemez (func1()[100] geçerli bir PHP sözdizimi değildir). Bu soruna yönelik geçici bir çözüm geçici bir değişken kullanmak ve bu ifadeyi iki satıra ayırmaktır, ancak bazen çok ayrıntılı, gizli kodlara yol açabilir.

Mücadelesi Ben bu deliklerin birkaç biliyor

(daha vardır eminim). Kod-golf tarzında bile olsa bir çözüm bulmak bile zor. Kazanan, dört Sözdizim Deliğinin tümü için en az karakterleri olan kişidir. $output = ...;, ... herhangi ; 's içermiyor:

Kurallar

  1. Beyanı bu formu bir çizgi olmalıdır.
  2. Sadece (hatta başarısız olduğu durumlarda) (izin yok özel işlevler veya eval) standart kütüphane fonksiyonlarını
  3. Beyanı olmayan çalışma sözdizimi varsayılan fonksiyonel ile aynı çalışır kullanırlar.
  4. Açıklama, E_STRICT | E_ALL ile herhangi bir türde sözdizimi hatası olmadan çalıştırılmalıdır.

sözdizimi Delikler

  1. $output = func_return_array()[$key]; - bir fonksiyonun döndürülen dizinin bir ofset keyfi (string veya integer) erişmek
  2. $output = new {$class_base.$class_suffix}();
  3. - rasgele bir dizge birleştirme yeni bir sınıf oluşturmak için kullanılan
  4. $output = {$func_base.$func_suffix}(); - isteğe bağlı dize birleştirme işlevi olarak adlandırılıyor
  5. $output = func_return_closure()(); - bir kapatma diyoruz başka fonksiyonu
+0

Dizi dereferencing (sizin 1. sözdizimi delik) zaten Felipe Pena tarafından gövdede taahhüt edilmiştir. – Artefacto

+0

@Artefacto Bu harika bir haber! Duyduğum son fısıltılar göz ardı edildi. Bunun için bir bağlantın var mı? –

+2

Bu alıştırmanın anlamsız olduğunu düşünüyorum. Daha az karakter daha net/daha verimli farklıdır. – Artefacto

cevap

8

gördüğüm tek çözüm geçici bir değişken içerir iade edilen, bu nedenle bazı (çok az) ad kirliliği yoktur. Bunların hepsi 4 kısaltılacak geçici değişken kod sıkma Herhangi yol:

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

Çıktı:

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

Bu şekilde değişken atamayı nasıl yapabileceğiniz çok ilginç. Bu sözdizimini daha önce hiç görmedim. –

2

Çözümümün biraz daha uzun Shauns daha ama ben olsa hepsini düşündüm. Hata durumunda bile orijinal sözdizimiyle aynı şekilde çalışmalıdır. Temelde bir satırda iki satıra izin vermek için üçlü sözdizimini kullanıyorum. Ayrıca, bir karakteri kaydettiğinden ve sayılarla başlayan değişkenlerin geçerli olmadığı için, geçici değişkeni ${''} yerine ${0} olarak değiştirdim.

aşağıda tablolar

line1; 
$output = line2; 

olası her durum için aşağıdaki açıklamaya özdeş midir.

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

Çözümümü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); 

?> 
İlgili konular