13.10.11

Blocks, closures y objetos

Cuando ando de paseo por el mundo Ruby (especialmente RoR) me suelo encontrar con bastantes do y end (ciertamente me recuerdan PASCAL), o en una sola linea { y }, esto es lo que llamamos convencionalmente bloques (de instrucciones).

# método de configuración
config :scope, do |bag|
  bag.set :key, 'value'
end

Nada nuevo, tampoco para aburrirse, lo bonito de este lenguaje es la manera en que maneja estos conceptos de bloques. Pero también tiene una sintaxis poderosa, breve y bastante agradable de leer y escribir.
¿Hago mal en preferir un lenguaje también por su estética?

Tampoco voy a dar una clase de bloques en ruby, pero me interesa en concreto el concepto de lambda y su utilización como callback en algunos escenarios cotidianos en los lenguajes de programación de alto nivel como lo es también PHP.
Y no hay que buscar demasiado, la versión mas reciente del pre-procesador de hipertexto ya venía con torta bajo el brazo, pues ofrece bastante potencial en la orientación a objetos así como con este bonito concepto que es un closure. De hecho, en php un closure por si mismo es un objeto, una clase.
// método de configuración
config('scope', function ($bag) {
  $bag->set('key', 'value');
});

Finalmente me parece que su funcionalidad es la misma, contener un grupo de instrucciones en un contexto aislado, sin importar si devuelve un resultado o no.

Así como el ejemplo de un método de configuración cualquiera se pueden dar otras alternativas mas flexibles, aquí otra definición:

// agregamos un nuevo libro en alguna colección
function add_book_to($user, Closure $describe) {
  $book = $user->books->build();
  $describe($book);
  $book->save();
}

// seleccionamos a un usuario
$me = user::first_by_name('Alvaro');

// agregamos el libro
add_book_to($me, function ($book) {
  $book->title = 'Fake title';
  $book->description = 'Fake description';
}); 

Y la verdad es que una función anónima implementada en php tiene bastantes desventajas a comparación de otros lenguajes, pero tampoco es inútil. Se pueden conseguir features interesantes en cuanto a flexibilidad en php.

Chiro-liro

7.9.11

¿Pachequés o flexo?

Disculpen el título. Nel, ni se que dije.

Bueno... aquí traigo otra de las cosas locas -y divertidas- que me laten de PHP, ya me dirán.
Trabajando un poco en un proyecto que tengo alojado en mi cuenta de GitHub quise darle la vuelta a un problema especifico: diseñar una API que fuese amigable y divertida a la vez, desde luego me refiero al lenguaje mismo y no más.

Así pues descubrí que dos conceptos pueden existir bajo el mismo nombre, y hablo en serio:

function foo()
{
}

class foo
{
}

¿Y que chingados con eso?

Pues eso, de alguna extraña forma php permite nombrar de la misma manera una función y/o clase. Esto evidentemente nos brinda la posibilidad de escribir una serie scripts de diversa índole bajo el mismo "namespace" o algo parecido.

Vamos a imaginar una librería para manejar sesiones:

session_start();

class session
{
  public static function fetch($item)
  {
    return $_SESSION[$item];
  }
  public static function assign($item, $value)
  {
    $_SESSION[$item] = $value;
  }
  public static function remove($item)
  {
    unset($_SESSION[$item]);
  }
}

function session($item, $value = NULL)
{
  if (func_num_args() === 1)
  {
    return session::fetch($item);
  }
  elseif (is_null($value))
  {
    session::remove($item);
  }
  else
  {
    session::assign($item, $value);
  }
}

En mi experiencia esto facilita las cosas de una forma sumamente agradable y consistente, si no me creen hagan la prueba.

¡Diviertanse!

3.9.11

Classy patch

Ahora que lo pienso no se si existe algo parecido a esto.

Diviertiendome pensé que sería divertido jugar con alguna otra cualidad de PHP. Hice un podo de research y no hallé al respecto así que me dedique a diseñar algo así.

// registramos el buen autoloader
spl_autoload_register(function($class)
{
  rescue($class);
});

// registramos filtros
function resolve(Closure $with = NULL)
{
  static $patch = array();


  if (func_num_args() === 0)
  {
    return $patch;
  }

  $patch []= $with;
}

// y los ejectuamos
function rescue($class)
{
 foreach (resolve() as $callback)
 {
   $callback($class);
 }
}

Si, es un sistema de autoload, sin embargo no es una convencional. Y tiene varias ventajas mas.

Pa' sonreír, ¿no?

31.8.11

Radical, un pensamiento natural

Lo que me fascina de los lenguajes es el potencial que tienen para mejorar nuestra concepción del pensamiento mismo. Cada día me sorprendo mas.

Pero hablemos al chile (y no hablo del país), yo no soy fanático ni mucho menos obsesivo con ningún lenguaje. Solo trato de ser justo y humano, al final todo es cuestión de gusto.

Aquí es donde entra el radicalismo, no me gusta la forma tradicional de programar ni 100% objetos, ni 100% funcional. Creo que una buena combinación de ambos es perfecta para mi: PHP

Cuando observamos Javascript no parece que todo fuera un objeto, pero así lo es. Así mismo pasa con Ruby, y así cualquiera se acostumbra. Ni hablar de JAVA. No lo uso ni de keyword...

Ando tratando de llevar todo lo que he aprendido al limite, explotando todos los medios para desarrollar algo loco, la verdad solo busco mas aprendizaje y no más. Si gustan revisen mi Github

Después de todo soy scripter, ya lo verán.

18.8.11

Nel pastel

Recién vagando por mi TL y en algún tema de @forosdelweb mo topé con éste enlace.
He visto cosas muy locas entre lenguajes, y una de las cosas que me gustan es la "negación infinita", si, ya se que suena raro pero así es.

$foo = TRUE;

if ( !!!!!!!!!!!!!!!!!!!!!!!! $foo)
{
  echo 'Damn.';
}

¿Saben lo que significa?
Como cuando te dicen "no digas nada", yo lo entiendo como un "not(say(null))" osea que me quedo igual, "dí algo", true.

function not($is)
{
  return !!! $is;
}

function say($something)
{
  return $something;
}

echo not(say(null)) ? 'algo' : 'nada';

La neta la primera vez que torcí un !! no entendía ni madres, sin embargo un poco de reflexión pachequera me aclaro las cosas, casi como leí en un tema acerca de lo siguiente (que en PHP, obviamente no es posible).

$a = 5;
$b = $a ++ 5; // Parse error: syntax error, unexpected T_LNUMBER in...

Lo que si, esto que dicen está chingón:

on PHP you can do this: if($a == $b) { echo "true"; } else { echo "false"; } : try to do that whith Python

No más chequen.

10.8.11

¿Donde quedó la bolita?

Una de las cosas chidas que aprendí de jQuery es la forma en que maneja los argumentos, de forma casi predictiva. A lo que me refiero es la manera en que permite que los argumentos de la derecha se puedan emplear hacía la izquierda y así sucesivamente.

jQuery.post( url, [data,] [success(data, textStatus, jqXHR),] [dataType] )

jQuery.post('url.php', { foo: bar }, function(){}, 'json');
jQuery.post('url.php', function(){}, 'json');

O algo así, la onda es que me late hacer lo mismo con PHP.

function foo($bar = '', $candy = 0, $does = array(), $nothing = NULL, $else = FALSE)
{
  if (is_integer($bar))
  {
    $candy = $bar;
    $bar = '';
  }

  if (is_array($candy))
  {
    $does = $candy;
    $candy = 0;
  }

  if (is_callable($does))
  {
    $nothing = $does;
    $does = array();
  }

  if (is_bool($nothing))
  {
    $else = $nothing;
    $nothing = NULL;
  }
}

Aquí la clave está en conocer bien el tipo de argumentos que necesita nuestra función, y en base a ello omitir o redefinir los argumentos. En el ejemplo se hace de forma muy abusiva, confusa y complicada.

Si una función espera mas de 4 argumentos entonces lo que yo hago es agrupar las opciones mas triviales y restantes en un solo último argumento a modo de arreglo asociativo. Así los primeros tres argumentos -los mas relevantes- son mas fáciles de comparar predictivamente, suponiendo que alguno de ellos es igualmente un arreglo asociativo para combinarlo con las últimas opciones.

function request($url, $method = 'GET', array $params = array())
{
  static $defaults = array(
    'url' => '',
    'vars' => array(),
    'method' => 'GET',
    'headers' => array(),
    'status' => 200,
    'timeout' => 30,
    'callback' => 'print',
  );


  if (is_array($url))
  {
    $params += $url;
  }


  if (is_array($method))
  {
    $params += $method;
  }


  $params = array_merge($defaults, $params);

  extract($params);
}

Aquí hay otro tip: el type-hinting de php es realmente útil en estos casos, neta. Esto cambia radicalmente nuestra forma de emplear una función, método o como se llame.

Así mismo la idea es trabajar directamente con la variable de opciones, o bien, usar extract() para abreviar.

Yo le llamo patrón de predicción.

7.8.11

Consola carajo

No se de donde saque la idea pero creo que sí. Solo que no se si es legal poner una imagen en el post, me da igual. Mejor no pongo la imagen.

Bueno, la neta nunca había usado la consola de php.

Como fanático xubuntero que soy pues me late usar cualquier terminal de consola, y eventualmente cuando desarrollo ando usándola. Casi siempre.
Con PHP no me refiero a programar scripts para la consola, sino usarla para ejecutar código interactivamente.

A chinga, me dije. He pecado de pe#$&\!.

Pues ya, la primer consola interactiva que emplee fue irb de Ruby o alguna de Javascript, no me acuerdo.

En corto, primero un $ php --help | grep shell

  -a               Run as interactive shell

¡Papas!

6.8.11

¿Tengo problemas?

Me he estado preguntando últimamente si tengo problemas para programar, que igual tiene que ver con la razón de que estoy loco o algo así.

No soy tan adicto de la programación orientada a objetos al puro estilo de JAVA, y si comparamos con Ruby o Javascript pues definitivamente no hay comparación. Menos aún con PHP.
Pero debo confesar que también pase por la obsesión de programar 100% objetos desde que conocí CodeIgniter, era algo bizarra su implementación OOP aún con PHP4. Desde ahí se me zafaron los tornillos, chale.

Pero igual con el paso del tiempo he ido tomando mis propias decisiones con respecto a determinado patrones, honestamente yo comencé como scripter empleando funciones y toda la cosa. Es más, antes de leerme un buen libro de Javascript pensaba que alert() era una función. Errado he.

En fin, no se ustedes pero al menos yo si me divierto programando cosas fuera de lo común, como implementar -seudos- singleton con funciones, factory, registry o incluso prototype con clases estáticas.

Singleton

function instance($class)
{
  static $set = array();

  if (empty($set[$class]))
  {
    $set[$class] = new $class;
  }

  return $set[$class];
}

// ejemplo

$foo = instance('stdClass');
$foo->bar = 'buzz';

echo instance('stdClass')->bar; // => buzz

Factory

function load($class)
{
  return new $class;
}

// ejemplo

$foo = load('stdClass');
$foo->bar = 'buzz';

echo load('stdClass')->bar; // error

Registry

function bag()
{
  static $set = NULL;

  if (is_null($set))
  {
    $set = new stdClass;
  }

  return $set;
}

function get($key, $value)
{
  bag()->$key = $value;
}

function set()
{
  return bag()->$key;
}

// ejemplo

$obj = new stdClass;
$obj->bar = 'buzz';

set('foo', $obj);

echo get('foo')->bar; // => buzz

get('foo')->bar = strtoupper($obj->bar);

echo get('foo')->bar; // => BUZZ

unset($obj->bar);

echo get('foo')->bar; // error

Prototype

class prototype
{
  private static $stack = array();

  public static function method($name, $callback)
  {
    self::$stack[$name] = $callback;
  }

  public static __callStatic($name, $args)
  {
    return call_user_func_array(self::$stack[$name], $args);
  }
}

// ejemplo

prototype::method('bye', function()
{
  echo 'Adios pinchi mundo!';
});

prototype::bye(); // => Adios pinchi mundo!

Me queda claro que puede no ser correcto, pero concluyo que es completamente valido. Además estoy seguro que no todo se puede conseguir sin objetos, de ser necesario uso objetos.
No soy religioso con respecto a ello.

Et voilà.

3.8.11

Chido One

Así fue mi carnal, de una búsqueda que me llevó menos de 5 segundos de mi estúpida vida copie y pegué los códigos necesarios para jalar al blog el chingón script que usa GoogleCode, el famoso con ganas google-code-prettify (aka PrettyPrint).

No le pienso dar crédito al primer resultado que me salio hasta ver por mi mismo que funciona y todo, ¿verdad?

PHP

<?= 'Hola pinche mundo!'; ?>

Javascript

(function(){
  console.log('esta es una prueba');
})();

HTML

para <strong>resaltar</strong> el código

CSS

/* que mas a menudo */
strong {
  text-shadow: 2px 2px 2px #000;
  content: "utilizo.";
}

FTW, ¿no?

Pues eso era todo, no más queriendo comprobar su efectividad.

WTF!

¿Que que pedo?
Okey, esta bien. Soy ese mero, un scripter común y corriente.

¿De que se trata todo eso?
Ni puta idea. Pero como me late la programeada voy a escribir de eso, sin censura.

Wey, ¿y si te atoran? No pus yo que, la neta chido el que me entienda, yo solo escribo porque que me pachequea.

Y mientras escribo esto fijo una regla semántica: aquellos términos que mi corrector de idioma en uso marque como mal escritos, dejaré como con énfasis.

Aquí el core, cosas que vengo escuchando mas a menudo, es scriptear un rato.
Si unos lo pueden hacer de forma profesional y casi dogmática, ¿por que no hacerlo al contrario pregunto me yo?

No más no se fijen de como escribo y parloteo, si se escribir bien, no mas me da hueva.