Flo

aus dem Wiki des Entropia e.V., CCC Karlsruhe
Wechseln zu: Navigation, Suche
Qsicon Ueberarbeiten.png Wir weisen darauf hin, dass möglicherweise nicht alle Beiträge den Anforderungen genügen. Die Anforderungen sind: Flos sind in Liste "flo" gespeichert, zur Ausführ- oder Compilierzeit werden durch den Code einzelne flo0, flo1, flo2, flo3 Variablen angelegt, die später dann auch zur Ausgabe verwendet werden.


Beiträge, die die Anforderungen erfüllen

#!/usr/bin/env ruby

flo = [ "dividuum", "syb", "fiji", "flowhase" ]

# flos sind keine arrayss1!
for i in 0..flo.size-1
  eval "flo#{i} = flo[#{i}]"
  puts "flo#{i} == \"" + eval("flo#{i}") + "\""
end


Dieses Perl (*duck*) kann ja keiner lesen!1) Daher:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defvar *flo-sequence* #("dividuum" "syb" "fiji" "flowhase")))

(defmacro make-individual-flo-variables ()
  (cons 'progn
        (loop for flo across *flo-sequence*
              for i from 0
              collect `(defvar ,(read-from-string (format nil "*flo~d*" i)) ,flo))))

(make-individual-flo-variables)

(dotimes (i 4)
    (format t "~&flo~d = ~a" i (eval (read-from-string (format nil "*flo~d*" i)))))
Lisplogo warning 128.png

Dreckiges C:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
const int flolen = 4;
static char *flos[] = {"dividuum","syb","fiji","flowhase"};
static char *proghead = "#include <stdio.h>\nint main(void){\n";
static char *progend =  "  return(0);\n}\n";
int main(void){
        int i; FILE *o;
        o=fopen("flo2.c","w");
        fputs(proghead,o);
        for(i=0;i<flolen;i++){
                fprintf(o,"  char *flo%d = \"%s\";\n",i,flos[i]);
                fprintf(o,"  printf(\"flo%%d ist %%s\\n\",%d,flo%d);\n",i,i); }
        fputs(progend,o);
        fclose(o);
        system("/usr/bin/gcc -o flos flo2.c;./flos;rm -f flo2.c flos");
        return(0);
}


Nu aber wirklich noch in Perl:

#!/usr/bin/perl

@flo = ( "dividuum", "syb", "fiji", "flowhase" );

for $i (0..$#flo) {
  eval "\$flo$i = \$flo\[$i\]";
  print "\$flo$i eq \"" . eval("\$flo$i") . "\"\n";
}


Gute alte Bash:

#!/bin/sh

flo="dividuum syb fiji flowhase"

n=0
for f in $flo
do
  eval flo$n=$f
  echo -n "flo$n == "
  eval echo \$flo$n
  n=$(($n+1))
done


Realisiert in PHP, Lisp, Perl, XML, Bash und XSLT und immernoch kürzer als die C-Version:

<?php
$flo = array( "dividuum", "syb", "fiji", "flowhase" );

$l = fopen("flo.lisp", "w"); $p = fopen("flo.pl", "w");
fwrite($l, '(progn (format t "~a" "<flo>")');
fwrite($p,'
print <<EOF
  <xsl:stylesheet version="1.0"
                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                  xmlns="http://www.w3.org/TR/xhtml1/strict">
  <xsl:template match="/">');
    for($i=0;$i<count($flo);$i++) {
      fwrite($l, "(format t \"~a~a~a\" \"<flo$i>\" \"$flo[$i]\" \"</flo$i>\")");
      fwrite($p, "flo$i == <xsl:value-of select=\"flo/flo$i\"/>\n");
    }
    fwrite($l, '(format t "~a" "</flo>"))');
    fwrite($p,'
  </xsl:template>
  </xsl:stylesheet>
EOF'."\n");
fclose($l); fclose($p);
system("sbcl --noinform --load flo.lisp --eval '(quit)' > flo.xml");
system("perl flo.pl > flo.xslt");
system("xsltproc flo.xslt flo.xml | grep -v xml");
?>

http://static.php.net/www.php.net/images/news/php-logo.gif Lisplogo warning 128.png http://www.mail-archive.com/copenhagen@perl.org/msg00162/logo_mermaid.png

Noch einmal in Ruby:

#!/usr/bin/env ruby

flo = [ "dividuum", "syb", "fiji", "flowhase" ]

# flos sind keine arrayss1!
flo.each_with_index do | f, i |
  instance_variable_set "@flo#{i}", f
  puts "flo#{i} = #{instance_variable_get "@flo#{i}"}"
end

Bloatiger Angebercode, der auch noch etwas völlig anderes macht

(Warnung: (Zumindest) als Lispprogramm ist dieses Beispiel ziemlich unsinning, und z.B. die PRINT-OBJECT-Methode widerspricht der gängigen Konvention.)

(defclass flo ()
  ((name :initarg :name :reader flo-name)
   (skill :initarg :skill :reader flo-skill)
   (notebook :initarg :notebook :reader flo-notebook)))

(defun slot-value-or-something (object &key (slot 'name) (something "without name"))
  (if (slot-boundp object slot)
      (slot-value object slot)
      something))

(defmethod print-object ((flo flo) stream)
  (format stream "~&~a is actually ~a and is good at ~a.~&He loves hacking on his ~a."
          (class-name (class-of flo))
          (slot-value-or-something flo)
          (slot-value-or-something flo :slot 'skill    :something "nothing")
          (slot-value-or-something flo :slot 'notebook :something "dulcimer")))

(defmacro def-flo-class (class-name &key name skill notebook)
  (macrolet ((make-slot-def (name)
               `(when ,name
                  `(,',name :initform ,,name))))
  `(defclass ,class-name (flo)
     ,(remove nil (list
                   (make-slot-def name)
                   (make-slot-def skill)
                   (make-slot-def notebook))))))

(def-flo-class |Flo0|
    :name "dividuum"
    :skill "DOOM"
    :notebook "old Dell")

(def-flo-class |Flo1|
    :name "Peter"
    :skill "math"
    :notebook "IBM Thinkpad")

(def-flo-class |Flo2|
    :name "Fiji"
    :skill "WOW"
    :notebook "I-have-no-idea")

(def-flo-class |Flo3|
    :name "flohase"
    :skill "hoppeln"
    :notebook "hasIbook")

(let ((flos (list (make-instance '|Flo0|)
                  (make-instance '|Flo1|)
                  (make-instance '|Flo2|)
                  (make-instance '|Flo3|))))
  (dolist (flo flos)
    (print flo)))
Lisplogo 256.png

Ru^W Objektorientiertes C

// Das aendern:
#include "/usr/local/lib/ruby/1.8/i386-freebsd5/ruby.h"

VALUE flo_init(VALUE self)
{
        char *flo[] = {"dividuum", "syb", "fiji", "flowhase"};
        int i;

        for(i = 0; i < 4; i++)
        {
                char varname[5];
                sprintf(varname, "@flo%i", i);  // Insecure!
                rb_iv_set(self, varname, rb_str_new2(flo[i]));
        }
}

VALUE flo_each(VALUE self)
{
        int i;
        VALUE vars = rb_funcall(self, rb_intern("instance_variables"), 0);
        VALUE varname = rb_ary_shift(vars);

        while(varname != Qnil)
        {
                rb_yield(rb_ary_new3(2, varname, rb_iv_get(self, RSTRING(varname)->ptr)));
                varname = rb_ary_shift(vars);
        }

        return(Qnil);
}

int main()
{
        VALUE flo;

        ruby_init();

        flo = rb_define_class("Flo", rb_cObject);
        rb_define_method(flo, "initialize", flo_init, 0);
        rb_define_method(flo, "each", flo_each, 0);

        rb_eval_string("Flo.new.each { |name,value| puts \"#{name.gsub(/^@/, '')} = #{value}\" }");

        return(0);
}

Fußnoten

1) Anmerkung zu: "Dieses Perl (*duck*) kann ja keiner lesen!"

Stimmt doch gar nicht! Ist ganz einfach:

map printf("%s = %s\n", [flo0..flo3]->[$_], [dividuum, syb, fiji, flowhase]->[$_]), 0..$#{@{[flo0..flo3]}};

(Kommentar von mgr: Genau, "0..$#{@{[flo0..flo3]}}" ... q.e.d. Danke für das gute Beispiel. Aber ernsthaft, es ging hier eben gerade *nicht* um Einzeiler, die will niemand.)


Und auch in python kann man Einzeiler schreiben:

print "\n".join(["%s = %s" % (k, v) for k, v in {"flo0":"dividuum", "flo1":"syb", "flo2":"fiji", "flo3":"flowhase"}.items()])