ruby-mine

exploring the mine

Ruby + 10 Quine

von bovi am 04.07.2011 (04 Uhr)

Ich habe gerade folgendes Quine von Yusuke Endoh gefunden:

1
2
# ruby
l=92.chr;eval s="s=s.dump[r=1..-2].gsub(/("+l*4+"){4,}(?!\")/){|t|'\"+l*%d+\"'%(t.size/2)};5.times{s=s.dump[r]};puts\"# python\\nprint(\\\"# perl\\\\nprint(\\\\\\\"# lua"+l*4+"nprint("+l*7+"\"(* ocaml *)"+l*8+"nprint_endline"+l*15+"\"-- haskell"+l*16+"nimport Data.List;import Data.Bits;import Data.Char;main=putStrLn("+l*31+"\"/* C */"+l*32+"n#include<stdio.h>"+l*32+"nint main(void){char*s[501]={"+l*31+"\"++intercalate"+l*31+"\","+l*31+"\"(c(tail(init(show("+l*31+"\"/* Java */"+l*32+"npublic class QuineRelay{public static void main(String[]a){String[]s={"+l*31+"\"++intercalate"+l*31+"\","+l*31+"\"(c("+l*31+"\"brainfuck"+l*64+"n++++++++[>++++<-]+++++++++>>++++++++++"+l*31+"\"++(concat(snd(mapAccumL h 2("+l*31+"\"110"+l*31+"\"++g(length s)++"+l*31+"\"22111211100111112021111102011112120012"+l*31+"\"++concatMap("+l*32+"c->let d=ord c in if d<11then"+l*31+"\"21002"+l*31+"\"else"+l*31+"\"111"+l*31+"\"++g d++"+l*31+"\"22102"+l*31+"\")s++"+l*31+"\"21002111010120211222211211101000120211021120221102111000110120211202"+l*31+"\"))))))++"+l*31+"\","+l*63+"\""+l*64+"n"+l*63+"\"};int i=0;for(;i<94;i++)System.out.print(s[i]);}}"+l*31+"\")))))++"+l*31+"\",0};int i=0;for(;s[i];i++)printf("+l*63+"\"%s"+l*63+"\",s[i]);puts("+l*63+"\""+l*63+"\");return 0;}"+l*31+"\");c s=map("+l*32+"s->"+l*31+"\""+l*63+"\""+l*31+"\"++s++"+l*31+"\""+l*63+"\""+l*31+"\")(unfoldr t s);t[]=Nothing;t s=Just(splitAt(if length s>w&&s!!w=='"+l*31+"\"'then 501else w)s);w=500;f 0=Nothing;f x=Just((if x`mod`2>0then '0'else '1'),x`div`2);g x= reverse (unfoldr f x);h p c=let d=ord c-48in(d,replicate(abs(p-d))(if d<p then '<'else '>')++"+l*31+"\"."+l*31+"\");s="+l*31+"\"# ruby"+l*32+"n"+l*31+"\"++"+l*31+"\"l=92.chr;eval s=\"+(z=l*31)+\"\\\"\"+s+z+\"\\\""+l*31+"\"++"+l*31+"\""+l*32+"n"+l*31+"\""+l*15+"\""+l*7+"\")"+l*4+"n\\\\\\\")\\\")\"########### (c) Yusuke Endoh, 2009 ###########\n"

Das besondere an diesem Quine?

1
2
3
4
5
6
7
8
9
10
11
$ ruby QuineRelay.rb > QuineRelay.py
$ python QuineRelay.py > QuineRelay.pl
$ perl QuineRelay.pl > QuineRelay.lua
$ lua QuineRelay.lua > QuineRelay.ml
$ ocaml QuineRelay.ml > QuineRelay.hs
$ runghc QuineRelay.hs > QuineRelay.c
$ gcc -Wall -o QuineRelay QuineRelay.c && ./QuineRelay > QuineRelay.java
$ javac QuineRelay.java && java QuineRelay > QuineRelay.bf
$ beef QuineRelay.bf > QuineRelay.ws
$ wspace QuineRelay.ws > QuineRelay.unl
$ unlambda QuineRelay.unl > QuineRelay2.rb

Und abschliessend:


$ diff QuineRelay.rb QuineRelay2.rb

Ich bin verstört…

 
Kommentare (2)

Methoden in Ketten legen

von skade am 02.04.2011 (16 Uhr)

Method chaining - also die implementierung einer Methode durch verketten mehrerer anderer ist durch Ruby on Rails zu einer gewissen Popularität gelangt. Während sich Rails hier auf ein einfaches Namenschema und alias verlässt, bietet DataMapper hier eine Technik an, die sich vorzüglich für einen Ausflug in Rubys Objektmodell eignet. Diese Gelegenheit will ich nicht an mir vorüber gehen lassen und die Implementierung namens Chainable hier vorstellen.

Chain


Vollständigen Artikel lesen...
 
Kommentare (1)

Mandelbrot Einzeiler

von bovi am 24.04.2010 (17 Uhr)

David Brady hat einen Mandelbrot Einzeiler geschrieben:


60.times{|a|puts((0..240).map{|b|x=y=i=0;until(x*x+y*y>4||i==99);x,y,i=x*x-y*y+b/120.0-1.5,2*x*y+a/30.0-1,i+1;end;i==99?'#':'.'}*'');}

Ich liebe Code der das Layout hinrichtet. Wobei sich streitet lässt, ob ein Stück Code mit mehr als 80 Zeichen wirklich noch ein Einzeiler ist.

Optimierte Version von Jan:


60.times{|a|puts (0..240).map{|b|x=y=i=0;x,y=x*x-y*y+b/120.0-1.5,2*x*y+a/30.0-1until x*x+y*y>4||98<i+=1;i>98?'#':'.'}*''}
 
Kommentare (1)

ein neuer Hook: respond_to_missing?

von bovi am 05.10.2009 (01 Uhr)

Seit ein paar Tagen gibt es eine neue Hookmethode mit dem Namen respond_to_missing? im Rubytrunk.


Vollständigen Artikel lesen...
 
Kommentare (7)

:Ruby.equal? :Perl # => true

von bovi am 08.09.2009 (21 Uhr)

Und sie sind doch ähnlicher als gedacht…

 
Kommentare (0)

Spass mit HEAD: inspizierbare Blockparameter in 1.9.2

von skade am 31.05.2009 (16 Uhr)

Es ist zwar noch eine ganze Weile bis Weihnachten, aber eins ist sicher: Ruby 1.9.2 kommt. Und mit ihm ein Herzenswunsch Yehuda Katz's, der es wegen später Einreichung nicht mehr in 1.9.1 geschafft hat, aber im trunk vorhanden ist: Proc#parameters. Einen kleinen Spass, den man sich damit leisten kann, findet ihr unter dem Link.


Vollständigen Artikel lesen...
 
Kommentare (3)

Simple Regexp Scanner

von murphy am 21.09.2008 (18 Uhr)

(Deutsche Übersetzung; Original auf murfy.de.)

Ich bin gerade dabei, den Java Scanner für CodeRay (Ticket #42 ^^) zu schreiben, und dachte, es wäre nett, eine Liste von eingebauten Typen zu haben, um sie hervorzuheben – wie String oder IllegalStateException. Ich wusste, dass TextMate recht gute Unterstützung für Java bietet, also schaute ich mir das Bundle genauer an.

Tatsächlich, irgendein schlauer Kerl hat dort einen ziemlich langen regulären Ausdruck in die Tokendefinitionen geschrieben:

support-type-built-ins-java = {
  name = 'support.type.built-ins.java';
  match = '\b(R(GBImageFilter|MI(S(ocketFactory|e(curity(Manager|Exception)|
    rver(SocketFactory|Impl(_Stub)?)?))|C(onnect(ion(Impl(_Stub)?)?|
    or(Server)?)|l(ientSocketFactory|assLoader(Spi)?))|IIOPServerImpl|
    JRMPServerImpl|FailureHandler)|SA(MultiPrimePrivateCrtKey(Spec)?|
    ...und so weiter über mehrere Bildschirmseiten...

Offenbar haben sie eine lange Liste von Typen in eine minimale Regexp umgewandelt, sicher mit Hilfe eine Scripts. Das war nicht ganz das, wonach ich gesucht hatte. Wie komme ich jetzt an die ursprüngliche Liste?


Vollständigen Artikel lesen...
 
Kommentare (3)

Bench - Ein Frühsommer-Hack

von janfri am 11.06.2008 (11 Uhr)

Wann hast Du das letzte mal die Bibliothek benchmark aus der Ruby Standardbibliothek benutzt? Kannst Du Dich noch erinnern, wie die Methoden heißen, die man braucht, um einen Benchmarkbericht zu erzeugen?

Ich muss jedes mal neu in der API-Dokumentation nachschauen, weil die Bibliothek für mich nicht gerade intuitiv ist, so dass ich die Benutzung immer wieder vergesse. Aber dem kann man ja Abhilfe schaffen…


Vollständigen Artikel lesen...
 
Kommentare (4)

Warum einfach...

von murphy am 12.02.2008 (20 Uhr)

...wenn’s auch kompliziert geht?


Vollständigen Artikel lesen...
 
Kommentare (1)

Quines höherer Ordnung

von cypher am 06.02.2008 (12 Uhr)

Quines sind bekanntermassen Programme die ihren eigenen Quelltext ausgeben.

Aber jetzt gibts was neues: Quines der 3. Ordnung. sigfpe hat ein kleines Haskell-Programm entwickelt:

q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']
main=q "q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']" "def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'" "def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end"

Führt man dieses Programm aus, erhält man ein Python-Programm:

def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'
q("def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'","def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end","q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']")

… welches wiederum ein Ruby-Programm produziert:

def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end
q("def e(x) return 34.chr+x+34.chr end;def q(a,b,c) print b+10.chr+'main=q '+e(b)+' '+e(c)+' '+e(a)+' '+10.chr end","q a b c=putStrLn $ b ++ [toEnum 10,'q','('] ++ show b ++ [','] ++ show c ++ [','] ++ show a ++ [')']","def q(a,b,c):print b+chr(10)+'q('+repr(b)+','+repr(c)+','+repr(a)+')'")

Und dieses Ruby-Programm produziert wieder das Haskell-Programm. Toll, oder?

 
Kommentare (2)

def !?

von murphy am 12.12.2007 (01 Uhr)

Jawohl :)

class Feeling

  def ~
    p :drunk
  end

  def !
    p :alert
  end

  def -@
    p :bad
  end

  def +@
    p :good
  end

end

feeling = Feeling.new

-feeling  # => :bad
+feeling  # => :good
!feeling  # => :alert
~feeling  # => :drunk
# >> :bad
# >> :good
# >> :alert
# >> :drunk

Der Fachmann/Die Fachmassaigiraffe sieht hier mehrere Dinge:

matz sagt:

For good news, I have no big change left.

 
Kommentare (6)

RubyInject

von cypher am 26.11.2007 (13 Uhr)

Laurent Sansonetti ist der Herr der bei Apple für Ruby verantwortlich ist. Neben dem Ruby Interpreter kümmert er sich auch um so sachen wie RubyCocoa, einer Ruby-ObjectiveC-Bridge, mit der man native OS X Programme in Ruby schreiben kann.

Und jetzt hat er RubyInject veröffentlicht.


Vollständigen Artikel lesen...
 
Kommentare (1)

String#to_proc

von cypher am 27.10.2007 (21 Uhr)

Rails hat Symbol#to_proc populär gemacht. So sehr dass es sogar Teil von Ruby 1.9 werden wird.

Und jetzt hat Reginald Braithwaite String#to_proc implementiert. Das sieht folgendermassen aus:
'x+1'.to_proc[2] # => 3
'x+2*y'.to_proc[2, 3] # => 8


Zugegeben, da wo jetzt Symbol#to_proc verwendet wird, braucht man String#to_proc nicht. Verglichen mit
%w[dsf fgdg fg].map(&:capitalize)
liest sich
%w[dsf fgdg fg].map(&'.capitalize')
nicht wirklich besser.

Aber was wenn wir noch keine entsprechende Methode haben? Z.B. um alle Werte in einer Liste mit zwei zu Multiplizieren?
(1..5).map &'*2' # => [2, 4, 6, 8, 10]
Oder eine Liste reduzieren:
(1..5).inject &'+' # => 15


Der Source Code für diesen nützlichen Hack steht unter der MIT Licence, und Herr Braithwaite hat auf seinem Blog natürlich einen (englischen) Eintrag wo er das ganze näher erklärt: String#to_proc
 
Kommentare (2)

Ruby - überall und jederzeit

von dethix am 17.10.2007 (21 Uhr)

Endlich kann man auch Musik beim Programmieren hören ;-)

 
Kommentare (5)

Syntax-Samstag: defined? Foo()

von murphy am 29.09.2007 (03 Uhr)

Dass man Methoden in Ruby auch groß schreiben darf, ist ja allgemein bekannt. Es gibt sogar Methoden wie Array, die genauso heißen wie eine Konstante. Die Namensräume von Konstanten und Methoden sind also getrennt.

Doch wie geht defined? damit um? Erkennt es, dass es zwei Objekte mit demselben Namen gibt?

# Ruby 1.8/1.9
Foo = 'Konstante'
def Foo
  'Methode'
end

Foo  # => "Konstante"
Foo()  # => "Methode"

defined? Foo  # => "constant"
defined? Foo()  # => "method"

Also: Wenn man eine großgeschriebene Methode auf Existenz testen will, muss man Klammern dahinter setzen.

 
Kommentare (1)