Flo: Unterschied zwischen den Versionen

aus dem Wiki des Entropia e.V., CCC Karlsruhe
(formatieren)
KKeine Bearbeitungszusammenfassung
 
(31 dazwischenliegende Versionen von 12 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
<div id="Vorlage_FIXME">
<div id="Vorlage_FIXME">
{| width="100%" border="0" cellspacing="8" cellpadding="0" style="background-color: #f9f9f9; border: 1px solid #f00; font-size: 95%; margin-top: 2px; margin-bottom: 2px; clear: both"
{| width="100%" border="0" cellspacing="8" cellpadding="0" style="border: 1px solid #f00; font-size: 95%; margin-top: 2px; margin-bottom: 2px; clear: both"
| style="width: 24px" | [[Bild:Qsicon Ueberarbeiten.png|24px]]
| style="width: 24px" | [[Bild:Qsicon Ueberarbeiten.png|24px]]
| 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.
| 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.
Zeile 6: Zeile 6:
</div>
</div>


  '''Wir sind die Flo, Widerstand ist zwecklos!'''


== Beiträge, die die Anforderungen erfüllen ==
== Beiträge, die die Anforderungen erfüllen ==
 
=== ruby ===
<pre>
<syntaxhighlight lang="ruby">
#!/usr/bin/env ruby
#!/usr/bin/env ruby


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


# flos sind keine arrayss1!
# flos sind keine arrayss1!
Zeile 19: Zeile 20:
   puts "flo#{i} == \"" + eval("flo#{i}") + "\""
   puts "flo#{i} == \"" + eval("flo#{i}") + "\""
end
end
</pre>
</syntaxhighlight>
 


===lisp===
Dieses Perl (*duck*) kann ja keiner lesen!<span id="footref1">[[#footnote1|<sup><small>1)</small></sup>]]</span> Daher:
Dieses Perl (*duck*) kann ja keiner lesen!<span id="footref1">[[#footnote1|<sup><small>1)</small></sup>]]</span> Daher:
{| cellpadding=5
{| cellpadding=5
|<pre>
|<syntaxhighlight lang="lisp">
(eval-when (:compile-toplevel :load-toplevel :execute)
(eval-when (:compile-toplevel :load-toplevel :execute)
   (defvar *flo-sequence* #("dividuum" "syb" "fiji" "flowhase")))
   (defvar *flo-sequence* #("dividuum" "syb" "fiji" "flowhase" "florolf" "FlorianJW")))


(defmacro make-individual-flo-variables ()
(defmacro make-individual-flo-variables ()
Zeile 36: Zeile 37:
(make-individual-flo-variables)
(make-individual-flo-variables)


(dotimes (i 4)
(dotimes (i 5)
     (format t "~&flo~d = ~a" i (eval (read-from-string (format nil "*flo~d*" i)))))
     (format t "~&flo~d = ~a" i (eval (read-from-string (format nil "*flo~d*" i)))))
</pre>  
</syntaxhighlight>  
|
|
|[[Bild:Lisplogo_warning_128.png]]
|[[Bild:Lisplogo_warning_128.png]]
|}
|}
 
=== C ===
Dreckig:
Dreckiges C:
<pre>
<syntaxhighlight lang="c">
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <errno.h>
#include <errno.h>
#include <unistd.h>
#include <unistd.h>
 
const int flolen = 6;
const int flolen = 4;
static const char *flos[] = {"dividuum","syb","fiji","flowhase","florolf", "FlorianJW"};
static char *flos[] = {"dividuum","syb","fiji","flowhase"};
static const char *proghead = "#include <stdio.h>\nint main(void){\n";
static char *proghead = "#include <stdio.h>\n"
static const char *progend =  "  return(0);\n}\n";
                        "int main(void){\n";
static char *progend =  "  return(0);\n"
                        "}\n";
 
int main(void){
int main(void){
         int i;
         int i; FILE *o;
        FILE *o;
         o=fopen("flo2.c","w");
         o=fopen("flo2.c","w");
         fputs(proghead,o);
         fputs(proghead,o);
         for(i=0;i<flolen;i++){
         for(i=0;i<flolen;i++){
                 fprintf(o,"  char *flo%d = \"%s\";\n",i,flos[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);
                 fprintf(o,"  printf(\"flo%%d ist %%s\\n\",%d,flo%d);\n",i,i); }
        }
         fputs(progend,o);
         fputs(progend,o);
         fclose(o);
         fclose(o);
         system("/usr/bin/gcc -o flos flo2.c;./flos;rm -f flo2.c flos");
         system("/usr/bin/gcc -o flos flo2.c;./flos;rm -f flo2.c flos");
         return(0);
         return 0;
}
}
</pre>
</syntaxhighlight>


===Perl===
Nu aber wirklich noch in Perl:
Nu aber wirklich noch in Perl:


<pre>
<syntaxhighlight lang="perl">
#!/usr/bin/perl
#!/usr/bin/perl


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


for $i (0..$#flo) {
for $i (0..$#flo) {
Zeile 84: Zeile 80:
   print "\$flo$i eq \"" . eval("\$flo$i") . "\"\n";
   print "\$flo$i eq \"" . eval("\$flo$i") . "\"\n";
}
}
</pre>
</syntaxhighlight>
===Perl===
<syntaxhighlight lang="perl">
#!/usr/bin/perl
 
@flo = ( "dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW" );
 
for $i (0..$#flo) {
  ${"flo$i"} = $flo[$i];
  print "\$flo$i eq \"" . ${"flo$i"} . "\"\n";
}
</syntaxhighlight>
===PHP===
<syntaxhighlight lang="php">
<?php
$flo = array( "dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW" );
 
foreach ($flo as $i => $x) {
  ${"flo$i"} = $flo[$i];
  echo "\$flo$i = \"" . ${"flo$i"} . "\"\n";
}
?>
</syntaxhighlight>


===Bash===
Gute alte Bash:
Gute alte Bash:


<pre>
<syntaxhighlight lang="bash">
#!/bin/sh
#!/bin/sh


flo="dividuum syb fiji flowhase"
flo="dividuum syb fiji flowhase florolf FlorianJW"


n=0
n=0
Zeile 101: Zeile 120:
   n=$(($n+1))
   n=$(($n+1))
done
done
</pre>
</syntaxhighlight>


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


{| cellpadding=5
{| cellpadding=5
|
|
<pre>
<syntaxhighlight lang="php">
<?php
<?php
$flo = array( "dividuum", "syb", "fiji", "flowhase" );
$flo = array( "dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW" );


$l = fopen("flo.lisp", "w"); $p = fopen("flo.pl", "w");
$l = fopen("flo.lisp", "w"); $p = fopen("flo.pl", "w");
Zeile 131: Zeile 151:
system("sbcl --noinform --load flo.lisp --eval '(quit)' > flo.xml");
system("sbcl --noinform --load flo.lisp --eval '(quit)' > flo.xml");
system("perl flo.pl > flo.xslt");
system("perl flo.pl > flo.xslt");
system("xsltproc flo.xslt flo.xml");
system("xsltproc flo.xslt flo.xml | grep -v xml");
?>
?>
</pre>
</syntaxhighlight>
|
|
|  
|  
http://static.php.net/www.php.net/images/news/php-logo.gif
[[Bild:php-logo.gif]]
[[Bild:Lisplogo_warning_128.png]]
[[Bild:Lisplogo_warning_128.png]]
http://www.mail-archive.com/copenhagen@perl.org/msg00162/logo_mermaid.png
[[Bild:perl_logo_mermaid.png]]
 
[[Bild:Bash-org.jpg|128px]]
[[Bild:Xslt.png|150px]]


|}
|}
===Ruby===
Noch einmal in Ruby:


== Bloatiger Angebercode, der auch noch etwas völlig anderes macht ==
<syntaxhighlight lang="ruby">
 
Und nun nochmal Ruby mit viel bloatigem Metaprogramming-Foo (Und etwas völlig anderes machend. Anm. v. [[Benutzer:Mgr|mgr]]):
<pre>
#!/usr/bin/env ruby
#!/usr/bin/env ruby
class Flo
  def self.metaclass; class << self; self; end; end
  def self.traits(*arr)
    return @traits if arr.empty?
    attr_accessor *arr
    arr.each do |a|
      metaclass.instance_eval do
        define_method( a ) do |val|
          @traits ||= {}
          @traits[a] = val
        end
      end
    end
    class_eval do
      define_method( :initialize ) do
        self.class.traits.each do |k,v|
          instance_variable_set("@#{k}", v)
        end
      end
    end
  end


  traits :name, :skill, :notebook
flo = [ "dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW" ]


   def to_s
# flos sind keine arrayss1!
    s = "#{self.class} is actually #{self.name} and is good at #{self.skill}\n\tHe loves hacking on his #{self.notebook}"
flo.each_with_index do | f, i |
  end
   instance_variable_set "@flo#{i}", f
  puts "flo#{i} = #{instance_variable_get "@flo#{i}"}"
end
end
</syntaxhighlight>
===JavaScript===
'cause JavaScript rocks:
<syntaxhighlight lang="JavaScript">
flo = new Array("dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW");
for (i in flo) {
  eval("flo"+i+" = flo["+i+"]");
  dump("flo"+i+" == "+eval("flo"+i)+"\n");
}
</syntaxhighlight>
===Lua===
Wir moegen Lua:
<syntaxhighlight lang="lua">
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
lua_State *L;
char *flos[] = {"dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW"};
char buf[1024];
void main() {
        char *p;
        int i;
        L = luaL_newstate();
        luaL_openlibs(L);
        for(i=0; i < 6; i++) {
                sprintf(buf, "flo%d", i);
                lua_pushstring(L, flos[i]);
                lua_setglobal(L, buf);
        }


class Flo0 < Flo
        p=buf;
  name "dividuum"
        for(i=0; i < 6; i++)
  skill "DOOM"
                p += sprintf(p, "print(\"flo%d = \" .. flo%d);", i, i);
  notebook "old Dell"
end


class Flo1 < Flo
        luaL_dostring(L, buf);
  name "Peter"
}
  skill "math"
</syntaxhighlight>
  notebook "IBM Thinkpad"
end
class Flo2 < Flo
  name "Fiji"
  skill "WOW"
  notebook "i have no idea"
end


class Flo3 < Flo
===C++11===
  name "flowhase"
<syntaxhighlight lang="c">
  skill "hoppeln"
#include <vector>
  notebook "hasIbook"
#include <string>
end
#include <cstdlib>
#include <fstream>


a = [ Flo0.new, Flo1.new, Flo2.new, Flo3.new ]
using namespace std;
a.each { |f| puts f }
</pre>


int main(){
vector<string> flo={"dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW"};
ofstream cpp_2("cpp_2.cpp");
cpp_2<<"#include <iostream>\n#include <string> \nusing namespace std;\nint main(){\n";
for(int i=0;i<flo.size();++i){
cpp_2<<"\tstring flo"<<i<<" =\""<<flo[i]<<"\";\n";
}
cpp_2<<"\tcout\n";
for(int i=0;i<flo.size();++i){
cpp_2<<"\t\t<<flo"<<i;
if(i+1==flo.size()){
cpp_2<<"<<endl;\n";
}
else{
cpp_2<<"<<\", \"\n";
}
}
cpp_2<<"}"<<endl;
cpp_2.close();
system("g++ cpp_2.cpp -o cpp_2; ./cpp_2");
return 0;
}
</syntaxhighlight>


Und nochmal das, was das Ruby-Programm "mit viel bloatigem Metaprogramming-Foo" macht, allerdings wiederum in Common Lisp gegossen:
== Bloatiger Angebercode, der auch noch etwas völlig anderes macht ==
<br>(Warnung: (Zumindest) als Lispprogramm ist dieses Beispiel ziemlich unsinning, und z.B. die PRINT-OBJECT-Methode widerspricht der gängigen Konvention.)
===Ruby===
Und nochmal das, was das Ruby-Programm "mit viel bloatigem Metaprogramming-Foo" macht, allerdings wiederum in Common Lisp gegossen:<br>
(Warnung: (Zumindest) als Lispprogramm ist dieses Beispiel ziemlich unsinning, und z.B. die PRINT-OBJECT-Methode widerspricht der gängigen Konvention.)


{| cellpadding=5
{| cellpadding=5
|<pre>
|<syntaxhighlight lang="ruby">
(defclass flo ()
(defclass flo ()
   ((name :initarg :name :reader flo-name)
   ((name :initarg :name :reader flo-name)
Zeile 255: Zeile 307:
     :skill "hoppeln"
     :skill "hoppeln"
     :notebook "hasIbook")
     :notebook "hasIbook")
(def-flo-class |Flo4|
    :name "florolf"
    :skill "konfusion"
    :notebook "Thinkpad")
(def-flo-class |Flo5|
    :name "FlorianJW"
    :skill "pirat"
    :notebook "I-have-no-idea")


(let ((flos (list (make-instance '|Flo0|)
(let ((flos (list (make-instance '|Flo0|)
                   (make-instance '|Flo1|)
                   (make-instance '|Flo1|)
                   (make-instance '|Flo2|)
                   (make-instance '|Flo2|)
                   (make-instance '|Flo3|))))
                   (make-instance '|Flo3|)
                  (make-instance '|Flo4|)
                  (make-instance '|Flo5|))))
   (dolist (flo flos)
   (dolist (flo flos)
     (print flo)))
     (print flo)))
</pre>
</syntaxhighlight>
|
|
|[[Bild:Lisplogo_256.png]]
|[[Bild:Lisplogo_256.png]]
|}
|}


=== Ru^W Objektorientiertes C ===
<syntaxhighlight lang="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", "florolf", "FlorianJW"};
        int i;
        for(i = 0; i < 6; i++)
        {
                char varname[7];
                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);
}
</syntaxhighlight>
== Die Enterprise-Loesung ==
Das Schlimmste aus beiden Welten.
<syntaxhighlight lang="c">
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <jni.h>
const char *flos[] = { "dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW" };
const int n_flos = sizeof(flos)/sizeof(char*);
unsigned char class[] = {
0xca, 0xfe, 0xba, 0xbe,
0x00, 0x00,
0x00, 0x33,
0, 0,
0x01, 0x00, 16, 'j', 'a', 'v', 'a', '/', 'l', 'a', 'n', 'g', '/', 'O', 'b', 'j', 'e', 'c', 't',
0x01, 0x00, 4, 'F', 'l', 'o', 's',
0x01, 0x00, 18, 'L', 'j', 'a', 'v', 'a', '/', 'l', 'a', 'n', 'g', '/', 'S', 't', 'r', 'i', 'n', 'g', ';',
0x01, 0x00, 6, '<', 'i', 'n', 'i', 't', '>',
0x01, 0x00, 3, '(', ')', 'V',
0x07, 0, 1,
0x07, 0, 2,
0x0C, 0, 4, 0, 5,
0x0A, 0, 6, 0, 8,
0x01, 0x00, 4, 'C', 'o', 'd', 'e',
};
int cp_i = 11;
FILE *cout;
void fputc16(uint16_t in, FILE *out) {
fputc(in >> 8, out); fputc(in & 0xFF, out);
}
uint16_t add_utf8(const char *string) {
size_t len = strlen(string);
fputc(0x01, cout);
fputc16(len, cout);
fputs(string, cout);
return cp_i++;
}
uint16_t add_string(const char *string) {
uint16_t utf8 = add_utf8(string);
fputc(0x08, cout);
fputc16(utf8, cout);
return cp_i++;
}
uint16_t add_name_and_type(const char *name, uint16_t type) {
uint16_t namei = add_utf8(name);
fputc(0x0C, cout);
fputc16(namei, cout);
fputc16(type, cout);
return cp_i++;
}
uint16_t add_field(uint16_t class, const char *name, uint16_t type) {
int nat = add_name_and_type(name, type);
fputc(0x09, cout);
fputc16(class, cout);
fputc16(nat, cout);
return cp_i++;
}
void make_flontainer(void) {
cout = fopen("Flos.class", "w");
class[9] = 1 + 10 + 5 * n_flos;
for(int i = 0; i < sizeof(class); i++) {
fputc(class[i], cout);
}
for(int i = 0; i < n_flos; i++) {
int ref;
char varbuf[16];
snprintf(varbuf, 16, "flo%u", i);
add_field(7, varbuf, 3);
add_string(flos[i]);
}
fputc16(0x0001, cout);
fputc16(0x0007, cout);
fputc16(0x0006, cout);
fputc16(0, cout);
fputc16(n_flos, cout);
for(int i = 0; i < n_flos; i++) {
fputc16(0x0001, cout);
fputc16(11 + i * 5, cout);
fputc16(3, cout);
fputc16(0, cout);
}
fputc16(1, cout);
fputc16(0x0001, cout);
fputc16(4, cout);
fputc16(5, cout);
fputc16(1, cout);
fputc16(10, cout);
fputc16(0, cout);
fputc16(17 + n_flos * 6, cout);
fputc16(2, cout);
fputc16(1, cout);
fputc16(0, cout);
fputc16(5 + n_flos * 6, cout);
fputc(0x2A, cout);
fputc(0xB7, cout); fputc16(0x0009, cout);
for(int i = 0; i < n_flos; i++) {
fputc(0x2A, cout);
fputc(0x12, cout); fputc(15 + 5 * i, cout);
fputc(0xB5, cout); fputc16(13 + 5 * i, cout);
}
fputc(0xB1, cout);
fputc16(0, cout);
fputc16(0, cout);
fputc16(0, cout);
fclose(cout);
}
const char *printer = "\
import java.lang.reflect.Field;\n\
\n\
public class Printer {\n\
public static void print() throws Exception {\n\
Flos floContainer = new Flos();\n\
Field[] flos = floContainer.getClass().getFields();\n\
\n\
for(Field flo : flos) {\n\
System.out.println(flo.getName() + \": \" + flo.get(floContainer));\n\
}\n\
}\n\
}\n";
void make_printer(void) {
FILE *out = fopen("Printer.java", "w");
fputs(printer, out);
fclose(out);
system("javac Printer.java");
}
void print_flos(void) {
JNIEnv *env;
JavaVMInitArgs args;
memset(&args, 0, sizeof(JavaVMInitArgs));
args.version = JNI_VERSION_1_6;
JavaVM *jvm;
JNI_CreateJavaVM(&jvm, (void**)&env, &args);
jclass printer = (*env)->FindClass(env, "Printer");
jmethodID print = (*env)->GetStaticMethodID(env, printer, "print", "()V");
(*env)->CallStaticVoidMethod(env, printer, print);
}
int main(void) {
make_flontainer();
make_printer();
print_flos();
return EXIT_SUCCESS;
}
</syntaxhighlight>


== Fußnoten ==
== Fußnoten ==
Zeile 273: Zeile 572:


Stimmt doch gar nicht! Ist ganz einfach:
Stimmt doch gar nicht! Ist ganz einfach:
<pre>
<syntaxhighlight lang="perl">
map printf("%s = %s\n", [flo0..flo3]->[$_], [dividuum, syb, fiji, flowhase]->[$_]), 0..$#{@{[flo0..flo3]}};
map printf("%s = %s\n", [flo0..flo5]->[$_], [dividuum, syb, fiji, flowhase, florolf, FlorianJW]->[$_]), 0..$#{@{[flo0..flo5]}};
</pre>
</syntaxhighlight>
(Kommentar von [[Benutzer:Mgr|mgr]]: Genau, "0..$#{@{[flo0..flo3]}}" ... q.e.d. Danke für das gute Beispiel.
(Kommentar von [[Benutzer:Mgr|mgr]]: Genau, "0..$#{@{[flo0..flo5]}}" ... q.e.d. Danke für das gute Beispiel.
Aber ernsthaft, es ging hier eben gerade *nicht* um Einzeiler, die will niemand.)
Aber ernsthaft, es ging hier eben gerade *nicht* um Einzeiler, die will niemand.)


Und auch in python kann man Einzeiler schreiben:
Und auch in python kann man Einzeiler schreiben:
<pre>
<syntaxhighlight lang="python">
print "\n".join(["%s = %s" % (k, v) for k, v in {"flo0":"dividuum", "flo1":"syb", "flo2":"fiji", "flo3":"flowhase"}.items()])
print "\n".join(["%s = %s" % (k, v) for k, v in {"flo0":"dividuum", "flo1":"syb", "flo2":"fiji", "flo3":"flowhase","flo4":"florolf", "flo5":"FlorianJW"}.items()])
</pre>
</syntaxhighlight>


[[Kategorie:Wissen]]
[[Kategorie:Wissen]]
[[Kategorie:Entropia]]
[[Kategorie:Entropia]]

Aktuelle Version vom 22. Februar 2013, 13:23 Uhr

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.
 Wir sind die Flo, Widerstand ist zwecklos!

Beiträge, die die Anforderungen erfüllen

ruby

#!/usr/bin/env ruby

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

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

lisp

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

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

(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 5)
    (format t "~&flo~d = ~a" i (eval (read-from-string (format nil "*flo~d*" i)))))
Lisplogo warning 128.png

C

Dreckiges C:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
const int flolen = 6;
static const char *flos[] = {"dividuum","syb","fiji","flowhase","florolf", "FlorianJW"};
static const char *proghead = "#include <stdio.h>\nint main(void){\n";
static const 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;
}

Perl

Nu aber wirklich noch in Perl:

#!/usr/bin/perl

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

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

Perl

#!/usr/bin/perl

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

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

PHP

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

foreach ($flo as $i => $x) {
  ${"flo$i"} = $flo[$i];
  echo "\$flo$i = \"" . ${"flo$i"} . "\"\n";
}
?>

Bash

Gute alte Bash:

#!/bin/sh

flo="dividuum syb fiji flowhase florolf FlorianJW"

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

PHP, Lisp, Perl, XML, Bash

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

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

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

Php-logo.gif Lisplogo warning 128.png Perl logo mermaid.png

Bash-org.jpg Xslt.png

Ruby

Noch einmal in Ruby:

#!/usr/bin/env ruby

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

# 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

JavaScript

'cause JavaScript rocks:

flo = new Array("dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW");
for (i in flo) {
  eval("flo"+i+" = flo["+i+"]");
  dump("flo"+i+" == "+eval("flo"+i)+"\n");
}

Lua

Wir moegen Lua:

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

lua_State *L;

char *flos[] = {"dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW"};
char buf[1024];

void main() {
        char *p;
        int i;

        L = luaL_newstate();
        luaL_openlibs(L);

        for(i=0; i < 6; i++) {
                sprintf(buf, "flo%d", i);
                lua_pushstring(L, flos[i]);
                lua_setglobal(L, buf);
        }

        p=buf;
        for(i=0; i < 6; i++)
                p += sprintf(p, "print(\"flo%d = \" .. flo%d);", i, i);

        luaL_dostring(L, buf);
}

C++11

#include <vector>
#include <string>
#include <cstdlib>
#include <fstream>

using namespace std;

int main(){
	vector<string> flo={"dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW"};
	ofstream cpp_2("cpp_2.cpp");
	cpp_2<<"#include <iostream>\n#include <string> \nusing namespace std;\nint main(){\n";
	for(int i=0;i<flo.size();++i){
		cpp_2<<"\tstring flo"<<i<<" =\""<<flo[i]<<"\";\n";
	}
	cpp_2<<"\tcout\n";
	for(int i=0;i<flo.size();++i){
		cpp_2<<"\t\t<<flo"<<i;
		if(i+1==flo.size()){
			cpp_2<<"<<endl;\n";
		}
		else{
			cpp_2<<"<<\", \"\n";
		}
		
	}
	cpp_2<<"}"<<endl;
	cpp_2.close();
	system("g++ cpp_2.cpp -o cpp_2; ./cpp_2");
	return 0;
}

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

Ruby

Und nochmal das, was das Ruby-Programm "mit viel bloatigem Metaprogramming-Foo" macht, allerdings wiederum in Common Lisp gegossen:
(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")

(def-flo-class |Flo4|
    :name "florolf"
    :skill "konfusion"
    :notebook "Thinkpad")

(def-flo-class |Flo5|
    :name "FlorianJW"
    :skill "pirat"
    :notebook "I-have-no-idea")


(let ((flos (list (make-instance '|Flo0|)
                  (make-instance '|Flo1|)
                  (make-instance '|Flo2|)
                  (make-instance '|Flo3|)
                  (make-instance '|Flo4|)
                  (make-instance '|Flo5|))))
  (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", "florolf", "FlorianJW"};
        int i;

        for(i = 0; i < 6; i++)
        {
                char varname[7];
                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);
}

Die Enterprise-Loesung

Das Schlimmste aus beiden Welten.

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#include <jni.h>

const char *flos[] = { "dividuum", "syb", "fiji", "flowhase", "florolf", "FlorianJW" };
const int n_flos = sizeof(flos)/sizeof(char*);

unsigned char class[] = {
	0xca, 0xfe, 0xba, 0xbe,
	0x00, 0x00,
	0x00, 0x33,
	0, 0,
	0x01, 0x00, 16, 'j', 'a', 'v', 'a', '/', 'l', 'a', 'n', 'g', '/', 'O', 'b', 'j', 'e', 'c', 't',
	0x01, 0x00, 4, 'F', 'l', 'o', 's',
	0x01, 0x00, 18, 'L', 'j', 'a', 'v', 'a', '/', 'l', 'a', 'n', 'g', '/', 'S', 't', 'r', 'i', 'n', 'g', ';',
	0x01, 0x00, 6, '<', 'i', 'n', 'i', 't', '>',
	0x01, 0x00, 3, '(', ')', 'V',
	0x07, 0, 1,
	0x07, 0, 2,
	0x0C, 0, 4, 0, 5,
	0x0A, 0, 6, 0, 8,
	0x01, 0x00, 4, 'C', 'o', 'd', 'e',
};

int cp_i = 11;
FILE *cout;

void fputc16(uint16_t in, FILE *out) {
	fputc(in >> 8, out); fputc(in & 0xFF, out);
}

uint16_t add_utf8(const char *string) {
	size_t len = strlen(string);

	fputc(0x01, cout);
	fputc16(len, cout);

	fputs(string, cout);

	return cp_i++;
}

uint16_t add_string(const char *string) {
	uint16_t utf8 = add_utf8(string);

	fputc(0x08, cout);
	fputc16(utf8, cout);
	return cp_i++;
}

uint16_t add_name_and_type(const char *name, uint16_t type) {
	uint16_t namei = add_utf8(name);

	fputc(0x0C, cout);
	fputc16(namei, cout);
	fputc16(type, cout);
	
	return cp_i++;
}

uint16_t add_field(uint16_t class, const char *name, uint16_t type) {
	int nat = add_name_and_type(name, type);

	fputc(0x09, cout);
	fputc16(class, cout);
	fputc16(nat, cout);

	return cp_i++;
}

void make_flontainer(void) {
	cout = fopen("Flos.class", "w");

	class[9] = 1 + 10 + 5 * n_flos;

	for(int i = 0; i < sizeof(class); i++) {
		fputc(class[i], cout);
	}

	for(int i = 0; i < n_flos; i++) {
		int ref;

		char varbuf[16];
		snprintf(varbuf, 16, "flo%u", i);
		add_field(7, varbuf, 3);

		add_string(flos[i]);
	}

	fputc16(0x0001, cout);
	fputc16(0x0007, cout);
	fputc16(0x0006, cout);

	fputc16(0, cout);

	fputc16(n_flos, cout);
	for(int i = 0; i < n_flos; i++) {
		fputc16(0x0001, cout);
		fputc16(11 + i * 5, cout);
		fputc16(3, cout);
		fputc16(0, cout);
	}

	fputc16(1, cout);
	fputc16(0x0001, cout);
	fputc16(4, cout);
	fputc16(5, cout);
	fputc16(1, cout);
	fputc16(10, cout);
	fputc16(0, cout);
	fputc16(17 + n_flos * 6, cout);
	fputc16(2, cout);
	fputc16(1, cout);
	fputc16(0, cout);
	fputc16(5 + n_flos * 6, cout);
	fputc(0x2A, cout);
	fputc(0xB7, cout); fputc16(0x0009, cout);
	for(int i = 0; i < n_flos; i++) {
		fputc(0x2A, cout);
		fputc(0x12, cout); fputc(15 + 5 * i, cout);
		fputc(0xB5, cout); fputc16(13 + 5 * i, cout);
	}
	fputc(0xB1, cout);

	fputc16(0, cout);
	fputc16(0, cout);

	fputc16(0, cout);

	fclose(cout);
}

const char *printer = "\
import java.lang.reflect.Field;\n\
\n\
public class Printer {\n\
	public static void print() throws Exception {\n\
		Flos floContainer = new Flos();\n\
		Field[] flos = floContainer.getClass().getFields();\n\
\n\
		for(Field flo : flos) {\n\
			System.out.println(flo.getName() + \": \" + flo.get(floContainer));\n\
		}\n\
	}\n\
}\n";

void make_printer(void) {
	FILE *out = fopen("Printer.java", "w");
	fputs(printer, out);
	fclose(out);

	system("javac Printer.java");
}

void print_flos(void) {
	JNIEnv *env;
	JavaVMInitArgs args;

	memset(&args, 0, sizeof(JavaVMInitArgs));
	args.version = JNI_VERSION_1_6;

	JavaVM *jvm;
	JNI_CreateJavaVM(&jvm, (void**)&env, &args);

	jclass printer = (*env)->FindClass(env, "Printer");
	jmethodID print = (*env)->GetStaticMethodID(env, printer, "print", "()V");
	(*env)->CallStaticVoidMethod(env, printer, print);
}

int main(void) {
	make_flontainer();
	make_printer();
	print_flos();

	return EXIT_SUCCESS;
}

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..flo5]->[$_], [dividuum, syb, fiji, flowhase, florolf, FlorianJW]->[$_]), 0..$#{@{[flo0..flo5]}};

(Kommentar von mgr: Genau, "0..$#{@{[flo0..flo5]}}" ... 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","flo4":"florolf", "flo5":"FlorianJW"}.items()])