Enviar respuesta 
 
Calificación:
  • 0 votos - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5
Why I f$%king hate PHP (and dyn typed languages)
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #1
Why I f$%king hate PHP (and dyn typed languages)
Ok, el título es producto de la inspiración divina, así que culpen a dios y no a mi...
Mentira, es producto de la ira que siento en estos momentos contra PHP, no de gratis, sino después de tener unos cuantos días codificando en ese perverso lenguaje.

Razón por la cual voy a dedicar este hilo única y exclusivamente a decir (y argumentar) porque detesto PHP y en general a los lenguajes dinámicamente tipados, al menos desde la perspectiva de la codificación.

Pueden añadir comentarios, los amantes de PHP se pueden defender (pero eso si, dejando a un lado las pasiones y simplemente argumentando). Recuerden que estoy juzgando el "lenguaje" (y seguramente las librerías), es decir, estoy viendo el asunto desde el punto de vista de la codificación y quizá un poco desde el punto de vista de la arquitectura, no desde el punto de vista del rendimiento, licencia, gustos, facilidad de aprender, etc.

"Let the flame war begin"

[Imagen: dmi-1.jpg]
(Este mensaje fue modificado por última vez en: 27-10-2010 07:23 PM por demian.)
27-10-2010 06:27 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #2
RE: Why I f$%king hate PHP (and dyn typed languages)
Caso de estudio (1)

Estoy programando un pequeño MVC (para poder mostrarles de ejemplo en clase y así demostrar la superioridad de usar MVC/Framework vs no usar MVC/Framework).

El MVC que estoy escribiendo implica el uso de Reflection Programming y otras cosas interesantes.

El punto es que para hacer una prueba de concepto hice unos cambios rápidos en una clase, me explico:

Tengo una clase A (los nombres de clases son ficticios), que tiene ciertos métodos, tales como getName, setName, etcétera, para acceder a algunas propiedades (métodos getters/setters). El cambio que estoy haciendo consiste en crear una clase B y mover muchas de las propiedades de A a B, e incrustar (componer) B dentro de A, es decir:

Código:
class A {
  private $name;

  // Otras cosas...

  public function getName() {
    return $this->name;
  }

  public function setName($name) {
    $this->name = $name;
  }

Luego del cambio que he explicado el párrafo anterior, voy a tener una clase B que tiene la propiedad name y los métodos getName y setName (no le veo el punto a publicarla, pueden usar un poquito su imaginación) de modo que la clase A quedaría de la siguiente forma al incrustar B y delegar los métodos getName y setName a la instancia interna de B.

Código:
class A {

  private $b; // La instancia de B que tiene el name ahora y a la que voy a delegar

  // Otras cosas...

  public function getName() {
    return $this->b->getName(); // Aquí estoy delegando getName a b->getName
  }

  public function setName($name) {
    $this->b->setName($name);  // Aquí estoy delegando setName a b->setName
  }

En el futuro me voy a deshacer en la clase A de los métodos getName / setName y pondré un getB / setB y accederé al atributo name directamente a través de la instancia de B, es decir, algo como getB()->getName() / getB()->setName(...), sin embargo, por lo pronto, no quiero hacer muchos cambios para no romper el código que actualmente está funcionando asumiendo que A tiene un getName / getName ¿Me siguen?, si alguien no me sigue puedo mejorar la explicación...

Eventualmente una compleja pero valiosa y poderosa pieza de código está invocando al método setName de forma reflexiva (se acuerdan lo de reflection programming), es decir, no es una invocación directa, sino que alguien (código) por medio del nombre de la clase A y el nombre del método setName o de la propiedad name (infiriendo el nombre del setter setName), almacenado por ejemplo en una variable tipo cadena que puede venir de un formulario en html, está invocando dinámicamente al método setName de A. Nuevamente, lean un poco sobre reflection programming para entender esto, al principio es un poco enredado, pero cuando lo entienden es muy poderoso y más adictivo que... Err, ¿el Mate?

Este código que hace la invocación dinámica no es nada trivial (ya lo van a ver en clase, probablemente ni me moleste en explicarlo, tendrán que tener Fe ;-) ) pero una vez puesto a punto puede ser una herramienta muy (MUY) poderosa que puede evitar tener escribir cientos (sino miles) de líneas de código repetitivas, aburridas y propensas a cometer errores.

En fin, en este punto, la situación es que lo que sea que se estoy tratando de hacer simplemente no está funcionando. Es decir, el atributo name de la clase B simplemente NO SE ESTÁ RELLENANDO CORRECTAMENTE.

¿El principal sospechoso? Lógico, la compleja pieza de código que hace la magia usando reflection programming ¿El resultado? Un buen rato depurando... para terminar frustrado concluyendo que el CODIGO que usa reflection está BIEN y NO TIENE ningún error Sad

Entonces se me ocurre ver algo simple, veamos si el método setName en A está delegando correctamente su llamada a la instancia de B... (es algo inocente, pero cuando se acaban las opciones...) y me encuentro con esto (en lugar de lo que debería ser en el trozo de código anterior):

Código:
public function setName($name) {
    $this->b->getName($name);  // Aquí estoy delegando setName a b->setName
  }

¿Ven la diferencia? ¿? ¿? Miren de nuevo... ¿No la ven aún? ¿? ¿? Vuelvan a mirar...

¡Exacto! En la parte de $this->b->getName($name); dice getName (con “g”) donde en realidad debería decir setName (con “s”).

¿Y qué está haciendo PHP al respecto? ¡Absolutamente nada! Está simplemente ignorando el parámetro $name que se le pasa a la función, que lógicamente está retornando el valor del atributo $name en B y que no altera/asigna en lo absoluto el valor del atributo $name (lógico, el que lo altera / asigna es setName, no getName)...

Ahora bien, antes que digan nada más, YO SE QUE EL ERROR ES MÍO, fue un error de copy/paste (copie el código del getter y puse el $name pero olvidé cambiar la “g” por “s”), pero ese no es el punto, el punto es que en Java (o en cualquier lenguaje compilado estáticamente tipado) tengo un compilador que hubiera detectado ese error de una vez y sin tanto problema (porque se revisa la firma del método invocado con respecto a la cantidad y tipo de los parámetros de la invocación), es decir, el compilador, sus validaciones y el sistema de tipos sirven como RED DE SEGURIDAD para detectar un sin fin de posibles errores sin tener que ejecutar el código... En el peor de los casos, el código en PHP se está ejecutando, es decir, no es un código abandonado en un else que casi nunca se ejecuta, así que PHP podría tener al menos la decencia de REVISAR en tiempo de ejecución que las firmas de los métodos concuerden.

En Java, eso hubiera corrido a la primera... ¿Ahora entienden un poco más por qué no me gusta PHP?

Un abrazo y si alguien que sepa un poco más de PHP puede contra-argumentar o decirme por que mi razonamiento es erróneo me encantaría escucharlo...

PS1: No se cual será el comportamiento en este caso de otros lenguajes dinámicamente tipados como Python o Ruby (estoy pensando en cual sería el comportamiento de JavaScript, pero no lo recuerdo), sería bueno tener información al respecto.

PS2: Si alguien encuentra algún typo o texto que no se entiende me avisa (me interesa arreglarlo)

PS3: Aunque no lo crean esto es parte del curso... buena parte del asunto es que tienen que aprender a ser críticos, a razonar y a ver el mundo de esta forma, a ver ejemplos en lenguajes que no conocen bien y sacar algunas conclusiones, así que la excusa de "No se PHP" no es váida Tongue

[Imagen: dmi-1.jpg]
27-10-2010 07:21 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
R3mmurd Sin conexión
Programmer
****

Mensajes: 176
Registro en: Jun 2010
Reputación: 0
Mensaje: #3
RE: Why I f$%king hate PHP (and dyn typed languages)
Interesante el caso, en Javascript cuando hay algún error de código, simplemente no se ejecuta la función al ser invocada, pero escribe los errores y advertencias en la consola de errores del navegador web, no pienso argumentar nada a favor de PHP ya que he pasado por algo semejante -.-

The world is Open Source!
Knowledge is Free!
27-10-2010 07:55 PM
Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #4
RE: Why I f$%king hate PHP (and dyn typed languages)
JavaScript se equivoca (en mi opinión) de la misma forma. Esto corre sin errores:

Código:
function foo() {
  alert("some message...");
}

foo("hello"); // "hello" es un parámetro de más, no concuerda con la firma del método foo

Por cierto, interesante este sitio web: http://www.webatic.com/run/programming/js_sandbox.php

[Imagen: dmi-1.jpg]
27-10-2010 08:09 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
R3mmurd Sin conexión
Programmer
****

Mensajes: 176
Registro en: Jun 2010
Reputación: 0
Mensaje: #5
RE: Why I f$%king hate PHP (and dyn typed languages)
=O Ciertamente se equivoca de igual manera, no verifica parámetros, de hecho lo acabo de probar y ni siquiera envía el error a la consola de errores, de hecho, el caso contrario también falla, hago la función que reciba un parámetro y la llamo sin parámetro e igual funciona, hice este

Código:
<html>
<head>
    <title>Prueba</title>

    <script language=javascript>

        function mensaje(x)
        {
            alert(x);
        }

    </script>
</head>
<body>
    <input type="button" value="presionar" onclick="mensaje()" />
</body>
</html>

y falla, envía el error a la consola de errores cuando es un error de sintaxis o algo así, aunque he visto que en diferentes navegadores se comporta diferente la identificación de errores (Sobre todo en el caso de PHP) en algunos navegadores corren algunas cosas que otros identifican como error

The world is Open Source!
Knowledge is Free!
27-10-2010 08:22 PM
Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #6
RE: Why I f$%king hate PHP (and dyn typed languages)
(27-10-2010 08:22 PM)R3mmurd escribió:  aunque he visto que en diferentes navegadores se comporta diferente la identificación de errores (Sobre todo en el caso de PHP) en algunos navegadores corren algunas cosas que otros identifican como error

En JavaScript te compro que tengas comportamientos diferentes en distintos navegadores, pero en PHP eso no es posible, ya que a pesar que PHP se usa para generar páginas WEB que se muestran en navegadores en el fondo el código corre por completo en el servidor, así que es independiente del navegador.

[Imagen: dmi-1.jpg]
27-10-2010 08:27 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
R3mmurd Sin conexión
Programmer
****

Mensajes: 176
Registro en: Jun 2010
Reputación: 0
Mensaje: #7
RE: Why I f$%king hate PHP (and dyn typed languages)
Bueno, esta es una pequeña anécdota que viví con PHP hace poco:

Tenia una pagina (Ej: foo.php) a la que se accedería desde dos paginas diferentes (faa.php y foofaa.php) (los códigos son ficticios).

Cuando faa.php hacia el direccionamiento, lo hacia sin pasar variables GET, en cambio cuando lo hacia desde foofaa.php si lo hacia
Ej: foo.php?variable=valor //Desde foofaa.php

En foo.php yo podia tener algo como
if ($_GET['variable'] == valor)
//haga lo que deba hacer

y en mi navegador no causaba ningún problema si entraba por alguna de las partes, si venia desde foofaa.php ejecutaba el bloque de código dentro de la condición, si venia desde faa.php no lo hacia y listo.

Lo correcto acá, es que si venia desde faa.php me diera error de variable no definida (cosa que si pasaba en el navegador de mi compañera de trabajo) lo cual corregimos usando la función que determina si una variable esta definida o no. Y dela misma manera pequeños errores de ese estilo o de otros, los detectaba un navegador y otro no, en ambos casos Mozilla Firefox, aunque es posible (pensándolo bien ahora) que el problema sea de la configuración PHP

The world is Open Source!
Knowledge is Free!
27-10-2010 08:42 PM
Encuentra todos sus mensajes Cita este mensaje en tu respuesta
demian Sin conexión
Administrator
*******

Mensajes: 1.808
Registro en: Jun 2010
Reputación: 0
Mensaje: #8
RE: Why I f$%king hate PHP (and dyn typed languages)
(27-10-2010 08:42 PM)R3mmurd escribió:  y en mi navegador no causaba ningún problema si entraba por alguna de las partes, si venia desde foofaa.php ejecutaba el bloque de código dentro de la condición, si venia desde faa.php no lo hacia y listo.

Lo correcto acá, es que si venia desde faa.php me diera error de variable no definida (cosa que si pasaba en el navegador de mi compañera de trabajo) lo cual corregimos usando la función que determina si una variable esta definida o no. Y dela misma manera pequeños errores de ese estilo o de otros, los detectaba un navegador y otro no, en ambos casos Mozilla Firefox, aunque es posible (pensándolo bien ahora) que el problema sea de la configuración PHP

Mmmm, interesante, ahora te entiendo lo que dices con respecto a los navegadores. Tendriamos que tener el código a mano para seguir especulando, pero el instinto me dice que es muy posible que el problema fuese la forma en que el navegador está enviando el request y no la forma en que se está ejecutando el código. Sería bueno saber de que forma estabas "incluyendo" a foo.php desde faa.php y desde foofaa.php ... Pero en cualquier caso es un bonito acertijo Big Grin

[Imagen: dmi-1.jpg]
27-10-2010 09:45 PM
Visita su sitio web Encuentra todos sus mensajes Cita este mensaje en tu respuesta
jrcsdev Sin conexión
pasante

Mensajes: 2
Registro en: Apr 2011
Reputación: 0
Mensaje: #9
RE:
(27-10-2010 08:42 PM)R3mmurd escribió:  Bueno, esta es una pequeña anécdota que viví con PHP hace poco:

Tenia una pagina (Ej: foo.php) a la que se accedería desde dos paginas diferentes (faa.php y foofaa.php) (los códigos son ficticios).

Cuando faa.php hacia el direccionamiento, lo hacia sin pasar variables GET, en cambio cuando lo hacia desde foofaa.php si lo hacia
Ej: foo.php?variable=valor //Desde foofaa.php

En foo.php yo podia tener algo como
if ($_GET['variable'] == valor)
//haga lo que deba hacer

y en mi navegador no causaba ningún problema si entraba por alguna de las partes, si venia desde foofaa.php ejecutaba el bloque de código dentro de la condición, si venia desde faa.php no lo hacia y listo.

Lo correcto acá, es que si venia desde faa.php me diera error de variable no definida (cosa que si pasaba en el navegador de mi compañera de trabajo) lo cual corregimos usando la función que determina si una variable esta definida o no. Y dela misma manera pequeños errores de ese estilo o de otros, los detectaba un navegador y otro no, en ambos casos Mozilla Firefox, aunque es posible (pensándolo bien ahora) que el problema sea de la configuración PHP

Ya llegó este (o sea yo,) a defender PHP... Hay cosas que nunca he investigado como la llamada (creo) Programación Reflexiva... ya tendré tiempo de eso... Ahora, con respecto a lo que menciona alejandro, ese error de cuando la variable existe o no existe es por la configuración del php... Si tienes display_errors en ON, te da ese error y algunos otros warnings... Para quien no se atreva a tocar el php.ini, lo más práctico es usar la funcion isset($variable) que devuelve true si la variable fue creada. En un ambiente de desarrollo, lo lógico es que display_errors sea ON, para corregir todos esos pequeños detalles, pero en producción, lo mejor es dejarla en OFF... Sobre lo otro que escribió el profesor, mejor me pongo a investigar antes de comentar sobre el tema.

NOTA: luego de responder, me di cuenta de la antiguedad del mensaje...

Saludos

Keep It Simple, Stupid
Código:
$me->sayYou("Hello!");
25-06-2011 10:24 PM
Encuentra todos sus mensajes Cita este mensaje en tu respuesta
Enviar respuesta 


Salto de foro:


Usuario(s) navegando en este tema: 1 invitado(s)