Discussion
Eduard Lebedyuk · Aug 16

DC Challenge: Write a quine in ObjectScript!

A quine is a computer program which takes no input and produces a copy of its own source code as its only output.

Wikipedia.

How about a fun challenge?

The task is to write a quine in InterSystems ObjectScript. It can be a class, or a method, or a routine, or just a line to be executed in a terminal. You decide!

Here's some resources you might consider useful:

Hard mode: do not use source code access functions.

Here's my (extremely uninspired, I know) attempt:

Class User.Quine
{

/// do ##class(User.Quine).Test()
ClassMethod Test()
{
    set sc = ##class(%Compiler.UDL.TextServices).GetTextAsString($namespace, $classname(), .str)
    write str
}

}

It produces this output:

How many different ways of producing a quine are there in ObjectScript?

90
4 0 15 377
Log in or sign up to continue

Store as quine.int
Run it by DO ^quine

quine ;; just a simple example
           ;; have any content
clone "ZL quine ZS quine1 P"  
           ;; may have more content

to avoid hardcode the actual routine name, you may do:
"ZL "_$T(+0)_" ZP"

Just print... no store, no nothing

myQuine ;A quine test

Just print it, no store, no nothing...

myQuine ; A test for a quine
   x "zl @$zn p"

That's all. And you can name the routine  as you like...

USER>d ^quine
quine    ;
         p
 
 
USER>

Ok, but how does it work?

The P command suppresses terminal screen display. It suppresses all terminal display, including displaying the terminal prompt.
Specifying P with no operand toggles display suppression.

Docs.

an overcomplicated solution:

Go() [] PUBLIC
{
    s cont = 0,pos = 1,lines = 0
    do {
        set line = $Text(Go+pos)
        set cont = cont + (($LENGTH(line,"{")-1)-($LENGTH(line,"}")-1))
        set lines = lines + 1
        set pos = pos + 1
    } while (cont > 0)
    s x=1
    if (x=1) a=}
    f i=0:1:lines $Text(Go+i),!
    s x=1
    if (x=1) a=}
    if (a=x) {
        b=a
    }
}

USER>d ^quine
 set q = $C(34) kill a //stolen from Wikipedia Java example
 set a($I(a)) = " set q = $C(34) kill a //stolen from Wikipedia Java example"
 set a($I(a)) = " set a($I(a)) = "
 set a($I(a)) = " write a(1),! "
 set a($I(a)) = " for i=1:1:a { "
 set a($I(a)) = "    write a(2),q,a(i),q,! "
 set a($I(a)) = " }"
 set a($I(a)) = " for i=3:1:a {"
 set a($I(a)) = "    write a(i),!"
 set a($I(a)) = " }"
 write a(1),! 
 for i=1:1:a { 
    write a(2),q,a(i),q,! 
 }
 for i=3:1:a {
    write a(i),!
 }

quine ; quine routine is a routine that prints itself content
"ZL "_$T(+0)_" ZP"
Q

Another solution:

quine
  for x=1:1:^ROUTINE($zn,0,0) write !,$g(^ROUTINE($zn,0,x))

USER>d ^quine
 
quine
        for x=1:1:^ROUTINE($zn,0,0) write !,$g(^ROUTINE($zn,0,x))
USER>

I wrote these several years ago - please do not code like this!

Quine 1:

s s=" s s=  w $E(s,1,5),$C(34),s,$C(34),$E(s,6,*)"  w $E(s,1,5),$C(34),s,$C(34),$E(s,6,*)

Quine 2:

s p="w $c(115,32,112,61,34)_p_$c(34,32,120,32,112)" x p

I am busy with mine. It is fiendish. Can a quine, having produced a copy of its own source code, delete itself and recreate itself using the output it generated?