how to use self 3.0

Upload: pablomarx

Post on 03-Apr-2018

219 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/28/2019 How to Use SELF 3.0

    1/62

    1

    How to Use SELF 3.0

    Ole Agesen

    Lars Bak

    Craig Chambers

    Bay-Wei Chang

    Urs Hlzle

    John Maloney

    Randall B. Smith

    David Ungar

    Mario Wolczko

    Welcome to SELF 3.0. This manual is designed to take you through the steps needed to install and

    start using SELF. It has three parts:

    Getting Started

    Exploring SELF

    Programming and Debugging

    We hope you enjoy using SELF. Good luck! The SELF Group

    Copyright (c) 1993, Sun Microsystems, Inc. and Stanford University. All Rights Reserved.

    Sun Microsystems, Inc

    2550 Garcia Avenue

    Mountain View, CA 94043 USA

    RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the government is subject to restrictions as

    set forth in subparagraph (c) (1) (ii) of the Rights in Technical Data and Computer Software Clause at DFARS

    252.227-7013 (Oct. 1988) and FAR 52.227-19(c) (June 1987).

    SOFTWARE LICENSE: The software described in this manual may be used internally, modified, copied and distrib-

    uted to third parties, provided each copy of the software contains both the copyright notice set forth above and the dis-

    claimer below.

    DISCLAIMER: Sun Microsystems, Inc. makes no representations about the suitability of this software for any pur-

    pose. It is provided to you "AS IS", without express or implied warranties of any kind. Sun Microsystems, Inc. dis-

    claims all implied warranties of merchantability, fitness for a particular purpose and non-infringement of third party

    rights. Sun Microsystems, Inc.'s liability for claims relating to the software shall be limited to the amount, if any of the

    fees paid by you for the software. In no event will Sun Microsystems, Inc. be liable for any special, indirect, inciden-

    tal, consequential or punitive damages in connection with or arising out of this license (including loss of profits, use,

    data, or other economic advantage), however it arises, whether for breach of warranty or in tort, even if Sun Microsys-

    tems, Inc. has been advised of the possibility of such damage.

  • 7/28/2019 How to Use SELF 3.0

    2/62

    2

    How to Use SELF 3.0 How to Install SELF

    Part I

    Getting Started

    To get started, you must install the SELF system from the distribution files, configure it for your

    computer, learn how to start and stop the SELF virtual machine, and create a SELF snapshot.

    1 How to Install SELF

    The SELF system can be installed from either tape or ftp. Installation consists of three steps: get-

    ting the archive files, performing the site installation, and setting up the working environment for

    an individual user.

    1.1 Getting the Archive Files

    The easiest way to get the SELF system is to use anonymous ftp to retrieve the files from

    self.stanford.edu. Archive files for the supported platforms, Sun-4s running SunOS 4.1.x orSolaris 2.3, reside in the directories /pub/Self-3.0.

    If you do not have access to the Internet, a tape can be obtained by sending email to

    [email protected]. There may be a small fee to cover handling and mediacosts.

    Create a temporary directory to hold the archive files and retrieve README, Install, and

    Archive file Contents

    README Describes how to install the system (similar to this chapter).Install Shell script to perform the installation.

    Self.tar.gz Archive containing the basic SELF system: the SELF virtualmachine and SELF source files describing the SELF world.

    Optional.Snapshot.tar.gz Contains a snapshot of the SELF world after reading in me-dium.self. An equivalent snapshot can be generated fromthe SELF source files in Self.tar.gz.

    Optional.VM.tar.gz Contains source code for the SELF virtual machine, roughly115,000 lines of C++. An installation of GNU g++ version

    2.4.5 is required to compile this code. This file is only neces-sary if you want to study or change the virtual machine or use

    the glue (see section 25 of the Reference Manual).

  • 7/28/2019 How to Use SELF 3.0

    3/62

    3

    How to Use SELF 3.0 How to Install SELF

    Self.tar.gz into this directory. The other three files, Optional.Snapshot.tar.gz,Optional.Glue.tar.gz, and Optional.VM.tar.gz are optional.

    1.2 Site Installation

    Once you have obtained the archivefi

    les you must execute the shell script Install to perform thesite installation. Install prompts you for the directory where the SELF site installation should re-side and then unpacks the archive files. The default installation directory is /usr/local/lib.

    Prior to running Install, you should be sure there is sufficient disk space. The disk space re-quirements for the unpacked archive files are:

    Self.tar.gz 5 Mb

    Optional.Snapshot.tar.gz 6 Mb

    Optional.VM.tar.gz 5 Mb

    Optional.Glue.tar.gz 400 Kb

    Type in the following to execute the Install script.

    % sh Install

    The archive files can be deleted when the site installation is complete.

    1.3 Running SelfUserSetup

    Before using SELF, each user must execute the script SelfUserSetup to configure the system forhis or her own use. SelfUserSetupwill do the following:

    checks your machine configuration and calculate the optimal setup for your machine.

    If the script tells you to add swap space please read section 1.4.

    adds a set of environment variable definitions to your ~/.cshrc file, based on the result ofthe previous calculation.

    makes a local copy of the SELF source files if requested.

    creates the .selfrc file in your home directory.

    The environment variable definitions added to the .cshrc file will not take effect until the next time

    a shell is created. To apply these definitions to the current shell, execute the UNIX command:

    % source ~/.cshrc

    Installation of SELF is now complete.

  • 7/28/2019 How to Use SELF 3.0

    4/62

    4

    How to Use SELF 3.0 How to Start the SELF Virtual Machine

    1.4 Adding Swap Space

    If the SelfUserSetup script tells you to extend the size of the virtual memory additional swapspace must be added to your system. Follow the instructions to add swap space.

    First check the size of your machines swap space. Under SunOS 4.x you can do this with the com-

    mand

    % pstat -s30640k allocated + 11944k reserved = 42584k used, 47552k available

    Under Solaris 2.x the equivalent command is:

    % swap -stotal: 30640k bytes allocated + 11944k reserved = 42584k used,47552k available

    The available number is the amount of swap space available for SELF.

    1. Now, subtract that number from the amount of swap space that the configure script said you

    need for SELF. The difference is the amount of swap space you must add.

    2. Find a disk with enough free space to hold the additional swap file. (You can use the UNIX dfcommand for this.)

    3. Become superuser.

    4. Create a swap file of the desired size:

    #mkfile 12m /u1/mySwapFile(The example creates a 12MB file named mySwapFile on the disk /u1. Any name may bechosen for the swap file. Remember to put this file on the disk you found in step 3.)

    5. Under SunOS 4.x, edit /etc/fstab, adding the following line:

    /u1/mySwapFile swap swap rw,noquota 0 0(Assuming that your swap file is named /u1/mySwapFile.)

    Under Solaris 2.x skip this item.

    6. Make the new swap file available to the system. Under SunOS 4.x type:

    # swapon -a

    Under Solaris 2.x type:

    # swap -a /u1/mySwapFile

    2 How to Start the SELF Virtual Machine

    You are now ready to run SELF. This section describes what youll encounter in the bare SELF

    world; a later section will tell you how to create a default worldof objects, a much more hospitable

    working environment.

    To start the SELF virtual machine, type Self at the UNIX prompt:

  • 7/28/2019 How to Use SELF 3.0

    5/62

    5

    How to Use SELF 3.0 How to Start the SELF Virtual Machine

    % SelfSelf Virtual Machine Version 3.0, Feb 30 1993 08:50:12Copyright 1989-93: The Self Group (type _Credits for credits)

    reading ~/.selfrcVM#

    Upon entering SELF, you are greeted by the prompt VM#, indicating that the system is ready to ac-

    cept input. You can now enter a SELF expression. This expression will be evaluated in the context

    of an object called the lobby, i.e., any message with an implicit receiver will be sent to the lobby.

    SELF will evaluate the expression and print the result.

    The bare SELF world has only a very few predefined objectsthe ones that are absolutely neces-

    sary for bootstrapping the system, like true and the prototypical string object (see section 23 ofthe Reference Manual). Thus, even basic methods like integer + are not defined:

    VM# 3 + 4A lookup error happened while sending the message "+"to .The receiver also did not understand the lookup error message"undefinedSelector:Type:Delegatee:MethodHolder:Arguments:" which

    was subsequently sent to it. -- Self VM

    #0 (:1): + = ( | _ self* = 3. _ :arg1 = 4. |"undefined selector error;this method automatically generated by the VM.")

    #1 (

  • 7/28/2019 How to Use SELF 3.0

    6/62

    6

    How to Use SELF 3.0 How to Run the Spy

    Normally, you will not work with the system in this crude, initial state; rather, youll use more

    comfortable worlds created by reading in scripts or snapshots. Later sections explain how to do

    these things.

    3 How to Run the SpyThe SELF system contains a system monitor, or spy, which displays information about the inter-

    nal workings of the system such as memory management and compilation. It can be turned on or

    off by evaluating_Spy: true or_Spy: false (the return value is theprevious state of the op-tion.) When the spy is active, it takes over the bottom portion of your screen with the following dis-

    play:

    The indicators in the left part of the display correspond to various internal activities and events.

    The bars on the right show how memory is being used. To understand how to interpret this display,

    see Appendix G of the Reference Manual. The spy can be useful simply to reassure you that SELF

    is still running during the longish pauses that sometimes occur when the garbage collector runs.

    We suggest that you start the spy now.

    By default, the spy displays on $DISPLAY,the default display for graphical output. If you wish to specify a differentdisplay, use the_SpyXDisplay:message to name another screen, such as obj:0.1.

    4 How to Interrupt Programs and Exit SELF

    Before going on, it is important to know how to exit from the virtual machine, interrupt a long

    computation, and stop and start the SELF process scheduler.

    VM activity VM memory object memory code cache

  • 7/28/2019 How to Use SELF 3.0

    7/62

    7

    How to Use SELF 3.0 How to Interrupt Programs and Exit SELF

    4.1 How to Exit the SELF Virtual Machine

    Table 1 summarizes the various ways to exit the SELF virtual machine. The first way forcefully ex-

    its the virtual machine no matter what it is currently doing and returns to the UNIX shell.

    4.2 How to Interrupt a SELF Program

    There are two ways to interrupt a running SELF program, Control-C and Control-\. The second

    way works even if the SELF process scheduler is not running.

    In response to the interrupt, you will see one of two things. If the SELF scheduler is not running,

    you will be returned directly to the VM# prompt. If the scheduler is running, you will be presented

    with a list of SELF processes (the process menu):

    Self 9> 100000 * 100000 do: []^C----------------Interrupt-----------------Ready:

    scheduling process 100000 * 100000 do: []Waiting:

    waiting process inputLoop------------------------------------------Select a process (or q to quit scheduler): 25Select | [a]bort, |

    | [b]ackground, || [s]uspend, || [r]esume, || [p]rint stack, |

    or | [n]o action | for process 25: aProcess 25 aborted.------------------------------------------

    Self 10>

    In this example, the loop was interrupted by typing Control-C, and the process menu was used to

    abort the process. If the user had typed q to quit the scheduler, all current processes would have

    been aborted along with the scheduler itself:

    Table 1 How to exit SELF

    If SELF prompts you with Type

    anything or nothing Control-Z, then kill -9 % to the UNIX shell

    VM# _Quit

    Self 17> _Quit

  • 7/28/2019 How to Use SELF 3.0

    8/62

    8

    How to Use SELF 3.0 How to Interrupt Programs and Exit SELF

    ...------------------------------------------Select a process (or q to quit scheduler): qScheduler shut down.------------------------------------------

    promptVM#

    The scheduler has been stopped, returning the user to the VM# prompt. The command promptstart restarts the scheduler:

    VM# prompt startSelf 11>

    Although the VM# prompt can be used to evaluate expressions directly, the scheduler supportsmuch nicer error messages and debugging, so it is usually best to run the scheduler. (The scheduler

    is started automatically when the default world is created.)

    4.3 Summary

    Certain virtual machine operations like garbage collection, reading a snapshot, and compilation

    cannot be interrupted; interrupts during these operations will be deferred until the operation is

    complete. As a last resort (e.g., if the system appears to be hung), you can force an abort by

    pressing Control-\five times in a row.

    Table 2 Interrupting and Exiting SELF

    Control-C Control-\ Control-D _Quit

    Interrupts

    current SELF

    process via

    SELF scheduler

    Interrupts

    current SELF

    process

    directly

    Signals end-of-file

    when reading

    standard input

    VM quit

    primitive

    The current prompt is

    Self 17>(the SELF scheduler is

    running)

    At prompt process menu process menu exits scheduler (goes

    to VM# prompt)exits VM

    Running

    SELF code

    process menu process menu no effect no effect

    The current prompt is

    VM#(the SELF scheduler is

    notrunning)

    At prompt no effect no effect no effect exits VM

    Running

    SELF code

    no effect returns to

    VM# promptno effect no effect

  • 7/28/2019 How to Use SELF 3.0

    9/62

    9

    How to Use SELF 3.0 How to Build and Save the World

    5 How to Build and Save the World

    You probably already know that there are two parts to SELF: a virtual machine (VM) that executes

    SELF programs, and a world of SELF objects (including programs) that live in the memory of the

    virtual machine. The world of objects can be saved into and later restored from a special kind of

    file, called a snapshot. A snapshot captures the state of the object world: that is, all the objects andmethods, but not the state of currently running processes. This section describes how to create a

    default object world by reading in the SELF source code provided with your distribution and how

    to save this world as a snapshot. (If you already have a snapshot, you can skip this section for now.)

    5.1 Creating the World

    To create the default object world:

    1. Start SELF:

    % SelfSelf Virtual Machine Version 3.0, Feb 30 1993 08:50:12Copyright 1989-93: The Self Group (type _Credits for credits)reading ~/.selfrcVM#

    2. Check the directory path that SELF will use to find source files:

    VM#_DirPath'.:~/self/self'

    The result string is a list of directories, separated by colons. A zero-length directory name is an

    abbreviation for the current directory. In particular, if_DirPath is the empty string, then thepath includes just the current directory. Paths may also include the tilde character (~), which is

    expanded as it is in the UNIX C-shell.3. If the directory containing your source files is not in the path, then change the path:

    VM#_DirPath: 'myDirectory'

    You can define a default value for_DirPath by including a line like_DirPath: '.:/tmp:~smith/self'

    in a file named .selfrc in your login directory.

    4. (Optional, but recommended.) Start the spy so you can watch the world fill up with objects:

    VM#_Spy: true

    5. Read in the default world. To do this, ask SELF to read expressions from the file all.sm:

    VM# 'all.sm' _RunScript

    Unless you have asked SELF not to print script names, you should see something like:

  • 7/28/2019 How to Use SELF 3.0

    10/62

    10

    How to Use SELF 3.0 How to Build and Save the World

    reading all.smreading init.selfreading allCore.sm. . .

    6. After all the files have been read in, SELF will start the process scheduler, initialize its cache ofpath names of well-known objects, and print:

    refilling path cache...done. 1705 entriesSelf 0>

    That last line is the SELF prompt indicating that the virtual machine is ready to read and evalu-

    ate expressions.

    Congratulations! You are now ready to explore the world of SELF objects. But, first you should

    save the world.

    5.2 Saving the WorldTo save the world, you need to write a snapshot file. This file consumes over 7Mb of disk space,

    so be sure to put it on a disk with enough free space. If the snapshot file name doesnt start with a

    slash, tilde, or dot, SELF will put it in the first directory in your DirPath (see step 2 above). Often,

    you will just name the file Snapshot and put it in the current directory:

    Self 1> './Snapshot' _WriteSnapshot'./Snapshot' this string is the value returned by _WriteSnapshotSelf 2>

    The next time you start SELF, you can just read in this snapshot (Snapshot _ReadSnapshot)and start working; you will not need to rebuild the default world.

  • 7/28/2019 How to Use SELF 3.0

    11/62

    11

    How to Use SELF 3.0 How to Read a Snapshot

    Part IIExploring SELF

    Now that you have built yourself a default SELF world, you are ready to read in your snapshot and

    explore this world using either text-based interactions or the graphical user interface.

    6 How to Read a Snapshot

    Start SELF if you are not already running it. Then, type the name of your snapshot file in single

    quotes followed by_ReadSnapshot.

    VM# 'Snapshot' _ReadSnapshotSelf 0>

    When the Self 0> prompt appears, you are ready to type in SELF expressions and explore theSELF world. The snapshot file name can be a relative or absolute path name, and tildes will be ex-

    panded as they are in the UNIX C-shell. If the first component in the file name is not the root, tilde,or the current directory, then SELF will search the sequence of directories set by_DirPath: for a

    file of the given name.

    As a shortcut, you can just type the name of the snapshot to the U NIX shell as if it were a command; UNIX will run

    whatever version of the SELF virtual machine it finds in your search path and then read the snapshot.

    7 How to Use the .selfrc File

    When SELF is first started, the virtual machine looks for the file .selfrc in your login directoryand, if it finds the file, evaluates all SELF expressions contained therein. This mechanism allows

    you to customize your SELF environment. For example, you can define custom shortcuts for fre-quently typed expressions. The .selfrcfile can also set virtual machine options such as _Dir-Path. Here is an annotated example:

  • 7/28/2019 How to Use SELF 3.0

    12/62

    12

    How to Use SELF 3.0 How to Evaluate Expressions

    _DirPath: '~/mySelfDirectory' set the VMs search path_SnapshotCode: true VM option to save compiled code with snapshotshell _AddSlotsIfAbsent: ( | Command shortcuts added to the shell object:

    spyOn = ( _Spy: true ). turn spy onspyOff = ( _Spy: false ). turn spy offgc = ( _GarbageCollect ). run garbage collectorquit = ( _Quit ). quit

    | )

    The .selfrcfile is executed immediately after SELF starts up. If you are starting up a snapshot,the .selfrcfile is executed before the snapshot is read in. Thus, any command shortcuts or other

    changes to the SELF world made by the .selfrcfile are overwritten when the snapshot is read in.However, virtual machine settings like_DirPath: and_SnapshotCode: survive.

    8 How to Evaluate Expressions

    Arbitrary SELF expressions can be typed at the SELF prompt. Each expression is evaluated and the

    result printed by the SELF read-eval-print loop. Here are some examples:

    Self 0> 3 + 47 The system reads the expression, evaluates it, and prints the result.

    Self 1> 20 factorial2432902008176640000

    Note that the system prints a prompt string such as Self 0> to indicate that it is ready to accept

    an expression. The number in the prompt string is an index into the command history (discussed in

    the next section). The value of the evaluated expression is always printed, even if the expression

    performs explicit output. For example, in the following example, the final 10 printed is the value

    of the do: expression:Self 2> 10 do: [| :i | (i * 2) print. print]0 2 4 6 8 10 12 14 16 18 10

    Multi-line expressions can also be entered. If the read-eval-print loop discovers that the expression

    typed so far has open (unbalanced) parentheses or brackets, it provides a continuation prompt (>>),allowing the expression to be continued on the next line. One can enclose a sequence of expressions in an

    extra set of parentheses to force the parser to read input lines until the final closing parenthesis. This handling of

    multiple line expressions is also used by the parser when evaluating expressions in script files (see

    section 16). For example:

  • 7/28/2019 How to Use SELF 3.0

    13/62

    13

    How to Use SELF 3.0 How to Evaluate Expressions

    self 3> 4 do: [| :i |>> (i printString, ! = , i factorial printString)>> printLine ]

    0! = 11! = 12! = 23! = 64

    Sometimes an input expression contains an error. For example:

    Self 3> snortNo snort slot found in shell .## Stack trace for process ##___Rcvr__Selector/Block_________File:line______Method-holder...#5 snort :1 shell#6 :1 shell

    The first line of the error explains the cause of the error. In this case, the message snort was not

    understood by the implicit receiver shell (the shell object is discussed in the next section). Sec-tion 13 describes all the kinds of errors that can arise in SELF programs.

    8.1 The shell object

    In order for a SELF expression to be evaluated, the meaning of self must be defined. When an

    expression is evaluated by the read-eval-print loop, the shell object plays the role of self:

    Self 5> self

    The shell is (indirectly) a child of the lobby:

    Self 6> shell parent parent parentlobby

  • 7/28/2019 How to Use SELF 3.0

    14/62

    14

    How to Use SELF 3.0 How to Evaluate Expressions

    The lobby is a common parent of many objects in the system and therefore provides a kind of lin-

    guistic common ground for the language. In particular, many useful objects such as true and all

    the prototype objects are accessible from the lobby. When the virtual machine evaluates the ex-pressions you type, messages implicitly sent to self get looked up first in the shell object, then in

    the lobby, then in the lobbys parents, and so on.

    The actual details of the read-eval-print loop are as follows: an expression is read from the standard input. The input

    is treated as if it were defining the body of a method in the doIt slot of the lobby. If the input is syntactically correct,the system installs the generated bytecodes as the doIt method and creates a new process which sends printIt tothe lobby. printIt is a SELF method (modifiable by the user) which calls doIt and then prints the result.

    Expressions read from a file by the_RunScript primitive, however, are handled slightly differ-ently: they are evaluated in the context of the lobby itself, not the shell object. This arrangement

    keeps the lobby free of temporary slots added by the user, preventing accidental name clashes. The

    programmer can thus safely augment the shell object with slots to store temporary results andshortcuts to reduce typing (i.e., methods playing the role of macros). For example:

    Self 7>_AddSlots: ( | p | ) Adds the slot p to the shell.shell

    Self 8> p: preferences Puts the preferecnces into the s slot.shell

    Self 9> p xDisplay: :0.1 Tell p to change the display used for the GUI.

    Many objects inherit

    from the lobby.

    ...

    lobby

    shell

    parentsof thelobby.

    In the expressions you

    type in, a message sent

    to self gets sent to the

    shell object, and meth-

    od lookup passes on

    from there through par-

    ent links.

  • 7/28/2019 How to Use SELF 3.0

    15/62

    15

    How to Use SELF 3.0 How to Use the Command History

    9 How to Use the Command History

    You may notice that each time you type an expression to the SELF prompt, the number in the

    prompt string advances. That is because each command you type is recorded in a command history

    object, along with its result. The number in the prompt string is a history number that can later be

    used to refer to a given command in order to examine the result of the command or to redo thecommand. Only the most recent N entries are saved. The value of N can be changed with history

    keep: n.

    You can view the most recent entries by typing history printRecords. The resulting outputwill look something like this:

    Self 5> history printRecords[0] 20 factorial[1] 3@4[2] ui start[3] ui add: 3@4[4] 17 parent

    You can use the history object to get the result of a command or to redo it:

    Self 6> history getResult: 4traits smallInt

    Self 7> history execute: 02432902008176640000

    Self 8> history getPrefix: '20 fac'[0] 20 factorial

    Self 9> history executePrefix: '17 par'traits smallInt

    These are verbose expressions: you will probably want to define shortcuts for the history opera-

    tions you use most frequently. You can add these shortcuts to your .selfrcfile so that they areautomatically added to shell object each time you start SELF. Some suggested shortcuts for his-tory operations are given in history.sm.

    10 How to Inspect and Print Objects

    There are various ways to examine and print objects, several that depend on parts of the default

    world being functional and one that does not.

    We recommend you do your programming through the graphical user interface, in which you can skip this section.

  • 7/28/2019 How to Use SELF 3.0

    16/62

    16

    How to Use SELF 3.0 How to Inspect and Print Objects

    10.1 Using inspect:

    The inspect:method attempts to print the contents of each slot in its argument. It also prints thedefinitions of methods contained in slots of the inspected object.

    Self 0> inspect: 3@4

    ( | _ parent* = traits point._ thisObjectPrints = true.^_ x

  • 7/28/2019 How to Use SELF 3.0

    17/62

    17

    How to Use SELF 3.0 How to Inspect and Print Objects

    }.{ 'Category: ui1BackwardsCompatibility'^ ##! sz = ( oldStyleRectangle from: self To: + sz maxPoint){ 'Category: ui1BackwardsCompatibility'^ maxPoint = ( x predecessor @ y predecessor)}.{ 'Category: ui1BackwardsCompatibility'^ rect = ( (0@0) #! maxPoint)}. | )

    traits point result printed by read-eval-print loop

    10.2 How objects are printed

    This section briefly discusses how objects are printed by the read-eval-print loop in the default

    world. For additional details, see the SELF Style Manual.

    Object-centric printing. Many objects in the default world understand messages that cause them

    to print themselves in an object-specific manner. The convention in the default world is for suchmethods to be invoked by sending print or printLine (which includes a newline after printing)to the object:

    Self 17> (3 @ 4) printLine3@4 This output is the result of sending the printLine message.3@4 This is the result printed by the read-eval-print loop.

    The message printString (and variations thereof) is used to get an objects printString withoutprinting it:

    Self 18> (3 @ 4) printString'3@4' The result is a string object, printed by the read-eval-print loop.

    Self 19> (3 @ 4) printString size3 The printString is 3 characters long.

    The read-eval-print loop. As previously mentioned, SELF sends printIt to the lobby when anexpression is typed at the prompt, after first installing the expression into the doIt slot in the shell.printIt attempts to print the result ofdoIt in an intelligent manner. It does this by invoking thename inferencer, a SELF-level mechanism that asks objects to print themselves if they know how,

    or tries to infer a name based on the objects location in the world otherwise. (This is not the case

    in the bare world, the minimal collection of objects you get when you start the SELF VM without

    reading in a snapshot or script files. In this case, printIt simply sends the_Print primitive, de-scribed in the next section, to the result ofdoIt.) The name inferencer uses thepath cache, a SELFobject that caches paths from the lobby to objects in the world. Objects that are reachable from the

    lobby (and thus appear in the path cache) are considered well-known. Here are some examples

    illustrating the name inferencer in the read-eval-print loop:

    Self 1> 3 @ 43@4 The name inferencer uses the printString method for points.

  • 7/28/2019 How to Use SELF 3.0

    18/62

    18

    How to Use SELF 3.0 How to Inspect and Print Objects

    Self 2> 17 parenttraits smallInt The name inferencer named this object based

    on its location in the world of objects.

    The name inferencer often generates a name that is actually a sequence of message sends that eval-

    uates to the named object. For example:

    Self 3> traits pointtraits point This name is an expression you can evaluate to get the object.

    The name traits point is a short version of the full path from the lobby to the traits for point ob-

    jects, traits graphics point.

    The name for well-known objects that also respond intelligently to printString is a combination of

    the path name and the printString. For example, the prototype point object has both a location part

    and a name part:

    Self 4> point0@0 This name has both a location part (point) and a printString part (0@0).

    In this case, the name part is short for prototypes graphics point.

    10.3 Primitive Printing and Object Reference Numbers

    The object printing and inspection mechanisms just discussed assume that certain basic facilities

    of the SELF world are working (e.g., string concatenation). This raises a bootstrapping question:

    what happens if these basic facilities themselves are broken and you need to debug them? The an-

    swer is to use the virtual machine primitives_Print and_AsObject.

    10.3.1 Object Reference Numbers

    _Print refers to objects by assigning them object reference numbers. An object reference numberis a small integer provided by the virtual machine as an object handle. One could use memory addresses

    for this but addresses can be large numbers that are cumbersome to remember and type. Besides, the address of an ob-

    ject may change after a memory scavenge or garbage collection; in contrast, object reference numbers remain invari-

    ant. Object reference numbers are printed as an integer surrounded by angle brackets, for example

    . The user can turn a reference number (an integer) into an object by sending it the_AsOb-ject primitive. For example:

    Self 5> 6 _AsObject3@4 The object reference number 6 refers to the point 3@4.

    The virtual machine only keeps track of the last n objects assigned reference numbers, where n is a configuration pa-

    rameter controlled by the_NumObjectIDs option (default:_NumObjectIDs: 1000). A given reference num-ber is valid as long as it is within the last n reference numbers assigned. After this, it is forgotten and sending it the

    _AsObject primitive will fail. However, reference numbers are not recycled during a SELF session, so an invalid his-

    tory number will not later be assigned to some other object; doing that could be very confusing!

  • 7/28/2019 How to Use SELF 3.0

    19/62

    19

    How to Use SELF 3.0 How to Inspect and Print Objects

    10.3.2 The_Print Primitive

    The_Print primitive is a basic object printing function implemented entirely in the virtual ma-chine._Print prints its receiver and returns nil as the result. The output of the_Print primitivealways lists at least the object reference number and slots of the receiver. It may also contain addi-

    tional information for certain kinds of objects. The following sections describe the output of the

    _Print primitive in greater detail.

    Plain objects. Ordinary objects respond to _Print by printing their reference number and a listof their slots._Print is a shallow operation: it does not recursively send_Print to the contentsof its slots. Instead, the contents of a slot is printed as follows:

    its literal form if the slot contains an integer, a float, or a string,

    true, false, nil, or lobby if the slot contains one of these objects,

    (3 @ 4) _Print: ( | _ parent* = . _ thisObjectPrints = true. ^ x = 3. _x: =

  • 7/28/2019 How to Use SELF 3.0

    20/62

    20

    How to Use SELF 3.0 How to Inspect and Print Objects

    Self 2> 18 _AsObject _Print: ( | _ parent* = . ^ # = . ^ ## = . ^alignToGrid: = . ^ asRectangle = . ^ copyX:Y:= . ^ normalize = . ^ r = . ^restrictTo: = . ^ separator = '@'. ^ translateBy: = . ^ xAxisReflect = . ^ yAxisReflect = .

    _ storeStringWorks = true. ^ #! = . ^ ##! = .^ maxPoint = . ^ rect = . | )nil

    Vectors. Object vectors and byte vectors display their array elements after their slots. The ele-

    ments are printed in the same manner as the contents of slots. The_VectorPrintLimit optioncontrols how many elements of a vector are printed. (The default is_VectorPrintLimit: 20.)

    Self 3> someVector _Print: ( | ^ parent* = . | object array: {true, , 2.45} )nil

    Integers andfl

    oats. Integers andfl

    oats are not assigned history numbers since their values can bedirectly printed and typed so easily.

    Self 4> 1.3 _Print1.3: ( | ^ parent* = . | ) The output of_Print. The float 1.3 has one parent slot.nil

    Self 5> 16r2f _Print A hexadecimal number (2F radix 16).47: ( | ^ parent* = . | ) Integers always_Print in decimal.nil

    Strings, special objects, processes, and mirrors. Strings and the true, false, nil, and lobbyobjects print their conventional form before their reference number and slot lists. Process objects

    print the special keyword process before their reference number and slot lists. Mirror objects(see the SELF World manual) print the short form of their reflectee in addition to the reference

    number and slots of the mirror.

    Self 6> 'tree' _Print'tree' : ( | ^ parent* = . | byte array: {116, 114, 101,101} ) Strings are surrounded by single quotes.nil

    Self 7> true _Printtrue : ( | _ parent* = . ^ asInteger = 1. ^ ifTrue:False:= . ^ not = false. ^ printString = 'true'. ^storeStringIfFail: = . ^ && = . ^ || = . ^ ^^ = . | )nil

  • 7/28/2019 How to Use SELF 3.0

    21/62

    21

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    Self 8> (reflect: 2@3) _Print Create a mirror on 2@3 and sends_Print to it.mirror : ( | ^ parent* = . _ thisObjectPrints = true. | )nil

    11 How to Use the SELF Graphical User Interface

    The SELF graphical user interface is a prototype browser for SELF. This prototype (hereafter re-

    ferred to as the ui) serves as an inspector, allowing the user to explore the SELF object world by

    pointing and clicking, and also as a rudimentary editing and modification environment. The ui was

    developed to explore some ideas in user interfaces for object-oriented programming environments

    [CU93] and is not intended to serve as a full-fledged environment for SELF.

    11.1 Requirements

    The ui requires an 8-bit color framebuffer. (It may work with deeper framebuffers but this has not

    been tested.) A GX accelerator is recommended for color operation; the ui may have poor perfor-mance on less powerful color frame buffers. The ui can run under OpenWindows or with any X11

    server, locally or remotely.

    11.2 Configuring the UI

    A slot in the preferences object determines the physical screen upon which the ui runs: xDis-play (defaults to :0.0).

    For a multi-headed machine (having more than one screen), or for remote operation, this slot can

    be set to another name as appropriate.

    11.3 Starting the UI

    It is recommended that you start the spy (the SELF system monitor) before starting the ui. Start the

    spy by sending the message_Spy: true. The spy will let you know whether pauses are due to

    SELF code being executed, the system dynamically compiling SELF code or, perhaps, a garbage

    collection taking place.

    To start the ui, simply send the message ui start. This puts a single object into the ui, the lobby.To start the ui with a different object visible, use ui startWith: obj.

  • 7/28/2019 How to Use SELF 3.0

    22/62

    22

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    11.4 Summary of Mouse Button Functions

    The ui primarily relies on the mouse for its operation, although it also uses several function keys.

    The following sections describe the operation of the ui in detail, but for starters, here is a short

    summary of the mouse button functions.

    11.5 Manipulating Objects in the UI

    The ui presents SELF objects as three-dimensional boxes floating in their own artificial reality (seebelow). The name of the object appears at the top, with an object menu button to the left. The slots

    of an object are depicted as wide strips on the face of the object, with the name in the left part of

    the strip, and the contents in the right part. At the bottom is a hidden-slots bar which can be used,

    via a menu, to hide or reveal slots.

    Menus do not reflect the philosophy of concreteness we espouse for the ui (see [CU90]). They have been added tothe ui as an expediency, to make this prototype more practical in the interim before a full-fledged user interface isconstructed.

    Table 1 Mouse button functions in the ui

    Mouse button Function Examples

    left grabbing sprouting contents, moving objects, popping up menu

    middle (color changing) (color version only; shift key must be down to initiate)

    right removing remove boxes from screen, hide slots, desprout arrows

  • 7/28/2019 How to Use SELF 3.0

    23/62

    23

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    The relationship between objects and the slots that contain (i.e., refer to) them is shown by arrows

    pointing from the slots to the objects. Objects can be moved about on the screen, the contents of

    their slots can be examined, and they can be removed from the screen. Each object provides menus

    to manipulate the object. The menus are accessed by pressing down the left mouse button over a

    designated area. Each object has a menu area at the top left (the small rectangular area), one menu

    per visible slot (at the left of the slot), and a hidden-slots bar at the bottom.

    Moving objects. Objects can be picked up and moved about on the screen by pointing to the face

    of the object (or the face of one of its slots), pressing down and holding the left mouse button, and

    moving the mouse. Letting go of the left mouse button drops the object.

    Examining slots. Clicking the left mouse button on a slots sprout button (the small, circular but-

    ton at the right hand end of the slot) causes the object referenced by the slot to display itself on the

    screen (sprout), connected to the slot by an arrow. The arrow can be removed by clicking the

    right mouse button over the sprout button. Navigating in the ui is performed by traversing slots to

    reach the desired object (the lobby object is a good starting point).

    Removing objects from the screen. Clicking the right mouse button on the menu box at the top leftof an object removes that object from the screen.

    Hiding and showing slots. Clicking the right mouse button on a slots menu box (at the left of the

    slot) will hide that slot. Hidden slots do not show on the face of the object. When some of an ob-

    jects slots are hidden, the hidden-slots bar displays how many slots are hidden. Pressing the left

    mouse button on the hidden-slots bar pops up a menu that lists all the hidden slots (or their anno-

    tations). Selecting an item from this menu makes the slot appear in the object. If an annotation is

    displayed, then the slots with that annotation are accessible via a sub-menu. Selecting the annota-

  • 7/28/2019 How to Use SELF 3.0

    24/62

    24

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    tion reveals all the slots with that annotation. In addition to hidden slots and annotations, this menu

    may include some of the special entries described in the table below.

    Except for theAll item, which is always present in the hidden slots menu, special menu items ap-

    pear only when there is at least one slot (or pseudo-slot) in that object matching that category.

    Hiding all slots (iconification). Clicking the right mouse button on the hidden-slots bar on the

    bottom of the box will hide all slots, effectively iconifying the object.

    Pseudo-slots. The ui permits access to certain parts of vectors, methods, and mirrors by way of

    pseudo-slots. For example, object vectors and byte vectors show their elements as pseudo-slots,

    in addition to showing their regular slots. Pseudo-slots have names enclosed in angle brackets.

    Table 2 Special items in the hidden slots menu

    Menu item Effect

    All Shows all slots

    Parents Shows only parent slots

    Public Shows only public slots

    Indexable Shows only the elements of the

    vector or byte vector part

    Well-known

    indexable

    Shows only those elements of the

    vector part that are well-known

    (i.e., recorded in the path cache)

    Table 3 Objects that have pseudo-slots in the ui

    Kind of object Pseudo-slots

    process process stack

    mirror the object that the mirror reflects (its reflectee)

    vector vector elements (the element indices are the names of the pseudo-slots)

    byte vector byte vector elements (the element indices are the names of the pseudo-slots)

    method byte code array, literal array, file name, file line number, source string

    block lexical parent

    generic activation receiver, expression stack, byte code position, plus all method pseudo-slots

    method activation selector, method holder, sender, plus all generic activation pseudo-slots

    block activation selector, lexical parent, sender, plus all generic activation pseudo-slots

  • 7/28/2019 How to Use SELF 3.0

    25/62

    25

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    The "object" menu. At the top left of each object is a rectangular area, which, when the left mouse

    is pressed, reveals a menu. The menu items are:

    Add slotallows you to add a new slot to an object. A typein window will appear in which

    you should type the name of the slot you wish to add. Selecting the apply button will add

    the slot; cancel will dismiss the typein.

    Add typein opens a typein window on the object. An expression may be entered into the

    typein, and evaluated. Evaluation takes place in the context of the object. All typeins sup-

    port some Emacs-like text editing operations. Arrow keys (or ^b, ^f, ^p and ^n) move the I-

    beam around. You can move to the beginning or end of a line with ^a or ^e. You can delete

    a line with ^k. ^s initiates a search; ^r initiates a reverse search. The character after the I-

    beam can be deleted with ^d, the character before with BackSpace or Delete.

    In addition to these features, you can also select text by dragging through it with the cursor-

    with the left mouse button depressed, and cut, copy and paste text using the keys of those

    names (or paste with ^y). Also, you can evaluate the text using Meta-Return.

    Drop dismissed the object from the ui. References summons an object which refers (in its indexable slots) to all the objects that re-

    fer to the original object.

    Children summons an object which refers (in its indexable slots) to all the objects which

    have the original object as a parent.

    Add method slotadds a new method slot called new_method_slot initialized to the method

    (self). Use the edit slotoption (see below) to change the name and definition of the meth-

    od.

    Add variable slotadds a new variable slot called new_variable_slot, initialized to nil. se

    the edit slotoption (see below) to change the name and definition of the slot.

    Add constant slotadds a new constant slot called new_constant_slot, initialized to nil. se

    the edit slotoption (see below) to change the name and definition of the slot.

    The slot menu. Each slot has a menu area at its left which, with the left button, can be used to

    manipulate the slot. Different kinds of slots have different options, drawn from this list:

    Edit slotallows you to edit the complete definition of the slot (including its name).

    Hide hides the slot.

    Implementors ofslot, slot: summon an object which can be followed to all the implemen-

    tors of messages with the same name.

    Want to find the implementors of a slot called foo but cant find a sender or another implementor? Using a typeincreate an object with a slot called foo, thus: (|foo|), then summon the implementors.

  • 7/28/2019 How to Use SELF 3.0

    26/62

    26

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    Senders summons an object which refers to all the methods which send the message with the

    same name as the slot.

    Messages sent by summons an object whose slots have the same names as the messages sent

    from the selected method. In conjunction with the implementors and senders options

    you can navigate the code in the system.

    Edit code allows you to edit the code of a method (but not its name or arguments).

    Remove slot, slot: removes the corresponding slot.

    The send menu. Objects may appear in the ui with a button at the lower right (next to the hid-

    den slots bar) that, when depressed, raises a menu which can be used to send unary messages to

    that object. (See below for how to add these menus.) Selecting a menu item sends the correspond-

    ing message to the object. The object returned by the message send will appear in the ui.

    Changing the contents of objects by grabbing arrows. [This is potentially a hazardous operation.]

    By setting allowArrowGrabbing to true in the preferences object (see below), the ui will al-low the contents of a slot to be changed by grabbing the head of its outgoing arrow with the left

    mouse button and dropping it over another object. When the arrowhead is grabbed, it changes into

    a square, indicating that it is waiting for a target. Dropping the square onto another object makes

    the arrow to point to that object, thereby changing the contents of the slot that the arrow is coming

    from. (Be sure to drop the square onto the target object, not merely near it.)

    Some arrow redirections are not currently permitted by the ui. These include moving an arrow for

    a pseudo-slot and moving an arrow to a method object that takes a different number of arguments

    than the original contents of the slot. In these cases, a warning is printed in the SELF shell and no

    change is made. Dropping an arrow over empty space aborts the operation.

    Be careful! Indiscriminately changing objects on which the rest of the system depends can break

    parts of the system, and redirecting arrows in the ui is tantamount to altering the running system.

  • 7/28/2019 How to Use SELF 3.0

    27/62

    27

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    If the ui and other parts of the SELF system begin behaving strangely (many errors and stack

    dumps), it may be because a crucial part of the system was changed unintentionally. In this case,

    quit SELF and start anew.

    Function key operations. Objects in the ui and the ui itself also respond to certain key press

    events from the keyboard. The relevant object is the object under the cursor at the time of the key

    press. If the cursor is on the background (i.e., not on any object), the key press generates a message

    to the ui itself.

    It is fairly easy to extend this functionality: the ui sendskeyPress: keyCode to the object under the cursor. Userinterface objects inherit keyPress: methods.

    11.6 Manipulating the UI in SELF code

    Operations in the ui can be carried out by sending messages to the ui object. The most useful of

    these messages is add:; the expression:

    ui add: obj

    Table 4 Function key operations

    Key Effect

    Stop (L1) On the background, quits the ui.

    Props (L3) Adds a mirror on the object into the ui.

    Cut (L10) Removes the object from the ui, but retains a reference to the object in a hidden

    clipboard.

    Copy (L6) Puts a reference to the object into the clipboard.

    Paste (L8) On the background, puts a copy of the object in the clipboard into the ui.

    On an object, adds the slots of the object in the clipboard to the given object.

    F1 Adds to the ui the display object to which you are pointing. For example, if you

    point to the senders button on an object and hit F1, the sendersBox object that

    implements the button will appear in the ui.

    F2 Finds the nontrivial parents of an object. Point to an object and press F2 to find

    any parents of the object which themselves have parents.

    F3 Traces the ancestry of an object. Point to an object, (move it to the lower left-

    hand corner of the screen), and press F3 to see all the objects ancestors whichthemselves contain parent slots. (Ancestors without parent slots are ignored in

    order to avoid cluttering things up with mere category objects.) F3 stops at the

    lobby, but you can go on by pointing to the lobby and pressing F3.

    F4 Summons all the well-known children of the object being pointed to. If there are

    more than 20, only 20 are shown.

  • 7/28/2019 How to Use SELF 3.0

    28/62

    28

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    makes the given object obj appear in the ui. To add the object to the ui with a send menu itemfor the unary message foo, use:

    ui add: obj With: foo

    The ui also responds to add:With:With:, add:With:With:With:, and add:WithMessag-

    es: (which takes a list of strings) to add the object with multiple send items.Nearly all the operations that can be carried out with the mouse in the ui can also be achieved by

    sending messages to ui. For details, see the requests client category in traits ui.

    11.7 Customizing the UI

    There are a number of ways to customize the way objects look and behave in the ui.

    Animation. . To turn off animation in the ui (sprouting boxes, entering and exiting boxes, arrow

    sprouting, menu sprouting), evaluate the expression ui animationOff. To turn it back on, eval-uate ui animationOn.

    Icon. If the ui finds a file with the name specified in preferences uiIconFile (see below; bydefault, a file in the current directory named ui.icon), it will use that file for its icon when it isiconified. The icon file is an X bitmap format file. If no icon file is found, the ui uses the default

    icon.

    Colors. If the ui finds a file with the name specified in preferences uiColorFile (see below;by default, a file in the current directory named ui.colors), it will use that file for the initial colorscheme. To create a color file, see section 12.8.

    Preferences. The ui uses the preferences object to control various options. To change a pref-

    erence, set the appropriate slot of the preferences object to the desired value. For example, to en-

  • 7/28/2019 How to Use SELF 3.0

    29/62

    29

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    able arrow grabbing, evaluate preferences allowArrowGrabbing: true. Some of the slotsfor preferences are summarized in the following table; inspect the object for a complete list:

    Box blueprints. The ui has a facility to customize the way an object first appears on the screen

    which slots are showing and what send pseudo-slots are shown. It does this by consulting a dic-

    tionary ofblueprints for objects, keyed on the structure of the object (the names of all its slots). If

    a blueprint is found, the ui uses that to determine which slots are shown and which are hidden, and

    what send pseudo-slots to add to the object. If no blueprint is found, a default policy is used. You

    can add your own blueprints to this dictionary; see the global boxBlueprint.

    11.8 Changing Colors

    On a system with a color framebuffer, pressing down and holding the middle mouse button while

    simultaneously holding down the shift key causes the cursor to enter color space. Once color space

    has been entered, the shift key may be released, but the middle button must remain pressed during the entire color

    changing operation.

    Color space allows the colors of the ui to be changed interactively. Whatever the cursor is pointing

    at when color space is entered is whats color will be changed. (This includes, for example, the

    background, the boxes, the text on the boxes, and the arrows. In the case of arrows, point to the

    round tail of the arrow to change its color.) Entering color space transports the cursor to the abso-

    lute location of the current color in the ui window. In color space, the horizontal axis measures hue

    and the vertical axis measures brightness. Pressing the left button down in while in color space

    (while keeping the middle button down) switches the vertical axis from brightness to saturation.

    Moving the cursor in color space interactively changes the color of the target elements. Releasingthe middle button leaves color space.

    The color scheme for the ui is automatically saved after color changing. A file is created to hold

    the color information. This files name is defined by the preferences uiColorFile slot (the

    Table 5 UI preferences

    Slot Name Description Default

    allowArrowGrabbing If true, allow arrowheads to be grabbed and dropped on other

    objects. Color version only.

    false

    blurArrows If true, enable experimental motion blur for arrows. Color

    version only.

    false

    blurBodies If true, enable experimental motion blur for bodies. Color

    version only.

    true

    uiColorFile File name to use for initial color scheme. Color version only. ui.colors

    uiIconFile File name to use for the ui icon. File should be in X bitmap

    format.

    ui.icon

  • 7/28/2019 How to Use SELF 3.0

    30/62

    30

    How to Use SELF 3.0 How to Use the SELF Graphical User Interface

    default is ui.colors). The ui checks for this file when it starts up and, if it finds it, uses the given

    colors. Otherwise, it uses the default colors.

    11.9 Leaving the UI

    The expression ui quit always aborts the ui. Under OpenWindows, you can also leave the ui bygoing to the border of the X window, popping up the Window menu, and selecting Quit; or by

    pressing function key L1 (labelled Stop on many keyboards).

  • 7/28/2019 How to Use SELF 3.0

    31/62

    31

    How to Use SELF 3.0 Finding Objects

    Part IIIProgramming and Debugging

    Here is the heart of the matter: writing and debugging your own SELF programs.

    12 Finding Objects

    The browse object implements an enumeration facility that allows you to find all the objects in thesystem with specific properties. The result of any browsing operation is a vector of mirrors.

    Example: find all objects having the selector upLex:

  • 7/28/2019 How to Use SELF 3.0

    32/62

    32

    How to Use SELF 3.0 How to Manipulate SELF Objects

    Example: find all methods sending the message evaluate:

    Example: find all objects referring to the object globals:.

    13 How to Manipulate SELF Objects

    This section explains how to change objects by adding, redefining, and removing slots. The funda-

    mental functionality for altering objects at this level is made available through mirrors. A mirroron a SELF object provides structural reflection facilities for that object (see section 16 of the Ref-

    erence Manual). In particular, mirrors implement methods for adding and removing slots to their

    object (reflectee). The two basic methods are addSlots: and removeSlot:. All programmingtasks in SELF can be built on top of these two methods. If you were to build a program manipula-

    tion facility, you would implement it using mirrors.

    However, when the system starts from a bare world, mirrors do not yet exist, so they cannot be

    used to build up the initial world of objects. Instead, the underlying primitives are used to directly

    modify objects. Actually, after the script defining mirrors has been processed, we could use mirrors to define and

    add slots to objects in all subsequent scripts. This is currently not done simply because it is somewhat faster to call the

    primitives directly. The primitives corresponding to the two mirror methods previously mentionedare:

    _AddSlots: and_RemoveSlot:

    Two other primitives are also provided:

  • 7/28/2019 How to Use SELF 3.0

    33/62

    33

    How to Use SELF 3.0 How to Manipulate SELF Objects

    _AddSlotsIfAbsent: and_Define:.

    The current implementation does not allow integers, floats, canonical strings, or blocks as the receiver of or argument

    to the programming primitives. Of course, their parent objects may be used as receivers.

    13.1 Adding SlotsBoth the addSlots:method of mirrors and the_AddSlots: primitive add all the slots of the ar-gument object (typically an object literal) to the receiver. If a slot already exists,_AddSlots: justassigns it a new value. The contents of read-only slots can be changed this way. Slots in the receiv-

    er but not in the argument object are left alone. Here are some examples:

    Self 0> (reflect: shell) addSlots:>> (reflect: (| x = (| |) |) )Ask a mirror to add a slot called x to the shell whose contents is an empty object.

    mirror on ()

    Self 1> inspect: x

    ( | | )

    Self 2> x _AddSlots: ( | Use the _AddSlots: primitive to add...>> a > b. An assignable slot initialized to nil.>> c = 3. A constant slot.>> h = ( history printRecords ). A method slot.>> q = ( | a. b > ^_ p > | ) (all other slots in this example are

    undeclared and have public semantics).

    Self 3> inspect: x( | a

  • 7/28/2019 How to Use SELF 3.0

    34/62

    34

    How to Use SELF 3.0 How to Manipulate SELF Objects

    Self 4> x _AddSlots: ( | a = 'new a' | )A change to x from previous example.

    Self 5> x _Print: ( | b = nil. c = 3. h = . q = . ^ p = nil.b: = inspect: p Inspect p.( | _ parent* = traits point.

    _ thisObjectPrints = true.^_ x inspect: p( | _ parent* = traits point.

    _ thisObjectPrints = true.^_ x

  • 7/28/2019 How to Use SELF 3.0

    35/62

    35

    How to Use SELF 3.0 How to Write a Program

    to the receiver all the slots found in its argument object. Thus, after performing the_Define:primitive, the receiver object contains a set of slots with exactly the same names, attributes, and

    contents as those specified in the_Define: primitives argument object. Like_AddSlots: and

    _RemoveSlot:,_Define: modifies the receiver in place and changes only that one object.

    Self 12> x _Print Object x from the preceding example.

    : ( | b = nil. c = 3. hello = . q = . ^ p = nil.b: =

  • 7/28/2019 How to Use SELF 3.0

    36/62

    36

    How to Use SELF 3.0 How to Write a Program

    Then use the Eval button to evaluate it, or press Meta-Return::

    We can test out the object by sending it some messages (such as + 7 and - 5) in a typein:

    We can now proceed to add more methods to provide further functionality. This is most easily ac-

    complished by using the add slot menu item, in which case a complete method definition should

  • 7/28/2019 How to Use SELF 3.0

    37/62

    37

    How to Use SELF 3.0 How to Write a Program

    be entered. Here, we have added methods to do multiplication and division, to clear the result, and

    to negate the result:

    Note that the precise division operator is /=.

    Of course, if we try to divide by zero we get an error notification:

  • 7/28/2019 How to Use SELF 3.0

    38/62

    38

    How to Use SELF 3.0 How to Write a Program

    In order to reduce the screen space, we can hide all the objects slots except the result slot (byclicking on the hidden slots bar at the bottom of the object with the right button, then using the left

    button menu on that bar to expose the result slot):

    However, it may be more convenient if the object displayed the result in its title bar, so that we

    could hide the slots completely. To do this we add a private slot called thisObjectPrints (setto true), and a printStringmethod:

    Note that the title updates.

    At this point we may consider the calculator finished, but for better organization it may be useful

    to break out the shareable behavior into a separate traits object. To do this we will create a separate

    object with just a result slot that inherits from our existing object, delete the result slot fromour current calculator, and then install the resulting objects in the globals and traitsnamespaces. The simplest way to do this is to make a copy of the current object, and delete some

    slots from the original object and the other slots from the copy.

  • 7/28/2019 How to Use SELF 3.0

    39/62

    39

    How to Use SELF 3.0 How to Write a Program

    First, we copy the existing object using copy:

    Next we delete the appropriate slots from each object (using the remove menu item on each slot),

    namely +, -, *, /, clear, negate and printString from one, and result and thisObject-Prints from the other.:

  • 7/28/2019 How to Use SELF 3.0

    40/62

    40

    How to Use SELF 3.0 How to Write a Program

    After that, we sprout the parent slot of the smaller object and redirect the arrow to the larger object:

    Finally, we add constant slots called calculator to traits applications and global ap-plications and hook these up to our prototypical calculator and to the calculator traits. The finalpicture should look something like this:

  • 7/28/2019 How to Use SELF 3.0

    41/62

    41

    How to Use SELF 3.0 How to Write a Program

    We can now summon a calculator from, say, the lobby, using calculator copy. We might wantto add some menu items (such as clear and negate) thus:

    We hope this has given you some ideas as to how to extend and improve this program. Happy

    hacking!

    The remainder of Section 14 describes the use of script files. If you stay entirely within the ui, you

    are unlikely to need any of this material, and can skip to the next section.

    14.2 Script Files

    A script is a text file containing a sequence of SELF expressions. The_RunScript primitive reads

    a scriptfi

    le and evaluates its expressions. Scriptfi

    les can be nested. The receiver of_RunScriptis a string specifying the script file. Standard UNIX shell conventions file naming conventions can

    be used (e.g., ../foo.self or ~/MySelfDir/foo.self). By convention, hand-writtenSELFfiles have the suffix .self, while those generated by the transporter end in .sm.

    The expressions contained in the script file are evaluated as if they had been typed at the prompt

    unmatched parentheses are used to indicate multi-line expressions as described in section 9

    but the expressions in a script file are evaluated in the context of the lobby, not the shell object, and

    their results are not printed. The expressions in a script file should not be separated by periods (al-

    though periods are still required to separate slot definitions in object literals). Parsing errors during

    a_RunScript of the nature unexpected token... found a . token... usually means that a periodwas found between expressions in the script file.

    Suppose the text file hello.self contains these lines:

  • 7/28/2019 How to Use SELF 3.0

    42/62

    42

    How to Use SELF 3.0 How to Write a Program

    'hello world' printLine Note: no periods at ends of expressions"This is a comment"'10 factorial is ' print10 factorial printLine

    This file can be read in (run) using the_RunScript primitive:

    > 'hello.self' _RunScripthello world10 factorial is 36288003628800

    14.3 Programming Using Script Files

    While you may create small objects interactively, most of your programming will be done by ed-

    iting and reading in script files containing object definitions. The first time a script file is read in, it

    creates some initial objects. Then, as bugs are discovered, the script file is modified with a text ed-

    itor and read in again to update the existing objects.

    This mode offile-based programming is supported by the object manipulation primitives previous-

    ly discussed plus one additional primitive. The primitive_AddSlotsIfAbsent: adds to the re-ceiver only those slots of its argument object (usually an object literal) that the receiver does not

    already contain. After performing this primitive, the receiver may contain some new slots, but all

    slots that previously existed in the receiver are unaffected. This primitive allows script files to be

    made idempotent: that is, reading them in multiple times has the same affect as reading them in ex-

    actly once.

    The use of_AddSlotsIfAbsent: and_Define: to build objects in script files usually followsthe following pattern. The argument to_AddSlotsIfAbsent: is an object literal containing a

    slot initialized to an empty object. A subsequent_Define: modifi

    es this newly-created object tocontain the appropriate slots. This pattern allows the programer to repeatedly edit and test an object

    definition. The first time the script file is read in, the object to be defined doesnt exist, and the

    _AddSlotsIfAbsent: creates a new empty object which_Define:fills in. When the script fileis subsequently edited and read in again, the_AddSlotsIfAbsent: has no effect (since the slotcontaining the object already exists) but the_Define: replaces the old version of the object withits new definition._Define: is used instead of_AddSlots: so that obsolete slots are removed.

    The combination of_AddSlotsIfAbsent: and_Define: is used instead of a single_AddSlots: operation so that the identity of the edited object is preserved. That is, all references

    to the old object now point to the new object. For example, if a traits object is rede fined, then the

    parent pointers in all clones of its prototype see the behavior defined in the new traits object.

    Suppose the following definition of a simple point is found in the file point.self:

    _AddSlotsIfAbsent: ( | ^ pointTraits = () | ) Define the initial point traits.pointTraits _Define: ( |

    ^ clone = ( _Clone ).| )

  • 7/28/2019 How to Use SELF 3.0

    43/62

    43

    How to Use SELF 3.0 How to Write a Program

    _AddSlotsIfAbsent: ( | ^ pointProto = () | ) Define the prototype.pointProto _Define: ( |

    _ parent* = pointTraits.^ x _AddSlots: ( | p1 | )shell

    Self 5> p1: ((pointProto clone) x: 5) y: 10

    This picture shows the objects that have been created:

    Now, suppose the definition of the point traits in the file point.self is changed to:

    _AddSlotsIfAbsent: ( | ^ pointTraits = () | )pointTraits _Define: ( | Redefined point traits.

    ^ clone = ( _Clone ).^ print = ( x print. @ print. y print. ).^ + p = ( (pointProto clone x: x + p x) y: y + p y ).

    | )

    _AddSlotsIfAbsent: ( | ^ pointProto = () | ) Define the prototype.pointProto _Define: ( |

    _ parent* = pointTraits.^ x

  • 7/28/2019 How to Use SELF 3.0

    44/62

    44

    How to Use SELF 3.0 How to Write a Program

    Self 6> point _RunScript

    This picture shows the resulting object changes:

    Reading in the edited script file modified the original pointTraitsobject in place, instead of cre-ating a new pointTraits object. This allows the new behavior to apply to existing clones of thepoint prototype such as p1. We can use_Print: to verify this:

    Self 7> pointTraits _Print: ( | ^ clone = . ^ print = . ^ + = . | )nil

    Self 8> p1 _Print: ( | _ parent* = . ^ x = 5. ^ x: =

  • 7/28/2019 How to Use SELF 3.0

    45/62

    45

    How to Use SELF 3.0 How to Write a Program

    oddballs applications _AddSlotsIfAbsent: ( | notebook = () | )notebook _Define: ( |

    _ parent* = traits oddball._ notes notebook addNote: 'This is a short note.'

    Note that addNote: returns the notebook object. This initially prints as becausethe notebook object is not in the pathCache. This problem can be corrected by updating the path-

    Cache:

    Self 10> pathCache refillrefilling path cache...done.'1642 entries'

    Self 11> notebook addNote: 'SELF is fun!'notebook

    Self 12> notebook addNote: 'This is a longer note. It goes on forseveral sentences and may print as multiple lines. Long notes makeit difficult to quickly scan a list of notes.'notebook

    In the last example, the string was typed without carriage returns and allowed to wrap around. If a

    carriage return were typed in the middle of this string, the parser would consider the expression

    complete and complain that the string literal is missing its trailing quote mark.

    The contents of the notebook can be displayed at any time:

    Self 13> notebook printNotesThis is a short note.SELF is fun!This is a longer note. It goes on for several sentences and mayprint as multiple lines. Long notes make it difficult to quickly

    scan a list of notes.notebook

    The notebook can be improved by having it store structured note objects rather than strings. In par-

    ticular, note objects can be given short titles to be printed when the user wants to quickly scan the

    contents of the notebook. Here are the appropriate object definitions:

  • 7/28/2019 How to Use SELF 3.0

    46/62

    46

    How to Use SELF 3.0 How to Write a Program

    traits applications _AddSlotsIfAbsent: ( | note = () | )traits note _Define: ( |

    parent* = traits clonable.printString = ( '*** ', title, ' ***\n', contents, '\n' ).

    | )

    prototypes applications _AddSlotsIfAbsent: ( | note = () | )note _Define: ( |

    _ parent* = traits note._ thisObjectPrints = true.^ title notebook addTitle: 'Structured Note' Contents: 'this is astructured note'notebook

  • 7/28/2019 How to Use SELF 3.0

    47/62

    47

    How to Use SELF 3.0 How to Write a Program

    Self 15> notebook printNotesThis is a short note.SELF is fun!This is a longer note. It goes on for several sentences and mayprint as multiple lines. Long notes make it difficult to quicklyscan a list of notes.*** Structured Note ***this is a structured note

    notebook

    Self 16> notebook printTitlesNo 'title' slot found in 'This is a short note.'.Sending method holder is notebook .## Stack trace for process ...

    The last expression, which was meant to print a list of note titles, produced an error because the

    notebook still contains some old, unstructured notesthat is, simple strings that do not understandthe message title. These notes (the first three added to the notebook) can be removed by manipu-

    lating the notebook objects note list directly. The notebook object is first entered to make its

    notes slot visible to expressions typed at the prompt (see section 10.2):

    Self 17> enter: notebookshell

    Self 18> notes removeFirst'This is a short note.'

    Self 19> notes removeFirst'SELF is fun!'

    Self 20> notes removeFirst'This is a longer note. It goes on for several sentences and mayprint as multiple lines. Long notes make it difficult to quicklyscan a list of notes.'

    Now printTitlesworks correctly:

    Self 21> notebook printTitlesStructured Notenotebook

    Self 22> notebook addTitle: 'Feature: searching' Contents: 'allow

    the user to find all notes containing a given substring'notebook

    Self 53> notebook addTitle: 'Feature: deleting' Contents: 'allowthe user to delete a note or a set of notes'notebook

  • 7/28/2019 How to Use SELF 3.0

    48/62

    48

    How to Use SELF 3.0 How to Interpret Error Messages

    Self 54> notebook printNotes*** Structured Note ***this is a structured note

    *** Feature: searching ***allow the user to find all notes containing a given substring

    *** Feature: deleting ***allow the user to delete a note or a set of notes

    notebook

    Self 55> notebook printTitlesStructured NoteFeature: searchingFeature: deletingnotebook

    You might want to view the structure of this program graphically. To do so, type:Self 56> ui startinitializing ui...creating colormap series . . . . . . . . . done.done.uiX

    Self 57> ui add: notebookuiX

    Self 58> ui add: note copyuiX

    The previous commands start the graphical user interface and make the notebook and a note object

    appear in it. Position the cursor over one of the these objects and press the function key F3. This

    will cause the inheritance hierarchy for the given object to be sprouted and arranged on the screen,

    as described in section 11.

    The last two notes in the notebook suggest some possible ways to extend and improve this pro-

    gram. You will probably think of many more. Happy hacking!

    15 How to Interpret Error Messages

    Five kinds of errors can occur during the execution of a SELF program: lookup errors, primitive

    errors, programmer defi

    ned errors, non-recoverable errors, and fatal VM errors. This section de-scribes the various errors in each category. For each category, the general layout of error messages

    in that category will be explained along with the format of the stack trace. Then a rogues gallery

    of the errors in that category will be shown.

  • 7/28/2019 How to Use SELF 3.0

    49/62

    49

    How to Use SELF 3.0 How to Interpret Error Messages

    By default, errors are handled by a set of methods defined in errorHandling.sm. For all errorsexcept non-recoverable and fatal VM errors, an object can handle errors in its own way by defining

    its own error handling methods. If the object in which an error occurs neither inherits nor defines

    error handling behavior, the VM prints out a low-level error message and a stack trace. The system

    will also resort to this low-level message and trace if an error is encountered while trying to handle

    an error.

    15.1 An Example

    Here is an expression that produces an error in the current system:

    Self 7> 100000 factorial

    The stack has grown too big.(Self 3.0 limits stack sizes, and cannot resume processes with stack overflows.)## Stack trace for process ##___Rcvr__Selector/Block__________File:line______Method-holder/location____#0 asSmallInteger smallInt:132 traits smallInt coercions#1

  • 7/28/2019 How to Use SELF 3.0

    50/62

    50

    How to Use SELF 3.0 How to Interpret Error Messages

    traits smallInt coercions

    the method holder of the method being executed. If the frame is a block activation,

    this is the frame method in which the block is defined (e.g., the block in frame #3

    is defined in the method factorial).

    A sequence of recursive calls is presented as a folded structure. In the above example the notation

    { ... }* 309 represent 309 occurrences of a sequence of activations with the same structure asactivations #3, #4, and #5. One can explore the stack in greater detail using the debugger, as dis-

    cussed in section 12.

    15.2 Lookup Errors

    Lookup errors occur when an object does not understand a message that is send to it. How the ac-

    tual message lookup is done is described in the Language Reference Manual.

    No foo slot found in shell .The lookup found no slot matching the selector foo.

    More than one system slot was found in shell .The matching slots are: oddballs and prototypes .

    The lookup found two matching systemslots which means the message is ambig-uous. The error message also says where the matching slots were found.

    Ambiguities can often be solved by changing parent priorities.

    No fish delegatee slot was found in .The lookup found no parent slot fish, which was explicitly specified as the dele-gatee of the message.

    15.3 Programmer Defined Errors

    These errors are explicitly raised in the SELF program to report errors, e.g. sending the message

    first to an empty list will cause such an error.

    Error: first is absent.Receiver is: list .

    Use the selectors error: and error:Arguments: to raise a programmer defined error.

    15.4 Primitive Errors

    Primitive failures occur when a primitive cannot perform the requested operation, for example, be-

    cause of a missing or invalid argument. Appendix H of the Reference Manual describes how prim-

    itive failures are handled.

    badTypeError: the _IntAdd: primitive failed.Its receiver was shell .

    The primitive failed with badTypeError.

  • 7/28/2019 How to Use SELF 3.0

    51/62

    51

    How to Use SELF 3.0 How to Interpret Error Messages

    The selector 12 could not be sent to shell because it is not a string.The primitive_Performexpects a string as its first argument.

    The selector add: could not be sent to shell because it does nottake 2 arguments.

    The primitive_Performreceived the wrong number of arguments.

    There are many other kinds of possible primitive errors (see Appendix H of the Reference Manu-

    al).

    15.5 Non-Recoverable Process Errors

    Errors that stop a process from continuing execution are referred to as non-recoverable errors.

    The stack has grown too big.(Self 3.0 limits stack sizes, and cannot resume processes with stackoverflows.)

    A stack overflow error occurs because the current version of SELF allocates a

    fixed size stack for each process, and the stack cannot be expanded. Self 3.0 cannot run a block after its enclosing method has returned.

    (Self cannot resume this process, either.)This error occurs if a block is executed after its lexically enclosing method has re-

    turned. This is call a non-LIFO block. Non-LIFO blocks are not supported by

    the current version of SELF.

    15.6 Fatal Errors

    In rare cases, the virtual machine may encounter a fatal error (e.g., a resource limit is exceeded or

    an internal error is discovered). When this happens, a short menu is displayed:

    Internal error: signal 11 code 3 addr 4 pc 0x1ac768.

    Do you want to:1) Quit Self2) Try to print the Self stack3) Try to return to the Self prompt4) Force a core dumpYour choice:

    The first line helps the SELF implementors locate the problem. Printing the SELF stack may pro-

    vide more information about the problem but does not always work. Returning to the SELF prompt

    is usually successful, but the system integrity may have been compromised as a result of the error.

    Execute the primitive_Verify to verify the virtual machines integrity; see Table 22 in AppendixH of the Reference Manual).

  • 7/28/2019 How to Use SELF 3.0

    52/62

    52

    How to Use SELF 3.0 How to Debug SELF Programs

    Since fatal errors usually arise from a bug in the virtual machine, please send the SELF group a bug

    report as described in section I-2.5, and include a copy of the error message if possible. If the error

    is reproducible please describe how to reproduce it.

    16 How to Debug SELF ProgramsThe default world contains a tty-based debugger. The debugger allows the user to control the exe-

    cution of a process and to examine the process stack. As described in [HCU92], the SELF system

    provides full source-level debugging with dynamic deoptimization. Debugging optimized code is

    therefore completely transparent to the user. Limited undocumented debugging facilities are also

    provided by the graphical user interface; see process.sm. This section assumes that the SELFprocess scheduler is running. If the current prompt is VM#, you can type prompt start to startthe scheduler:

    VM# prompt startSelf 1>

    16.1 Examining an Error

    When an error occurs, the scheduler suspends the active process and prints out an appropriate error

    message. (A complete list of possible error messages is given in section 14.) If the error message

    is too vague to discover the bug, you can attach the erroneous process to the debugger and explore

    the stack.

    A new process is created for each expression evaluated by the read-eval-print loop. When an error occurs, the process

    is suspended and the debugger can be used to explore its stack.

    Suppose you typed the following erroneous expression at the prompt:

    Self 4> | i attach attaches the process that most recently encountered an errorProcess has been attached to the debugger.No i slot found in .Sending method holder is shell .shell = (| i

  • 7/28/2019 How to Use SELF 3.0

    53/62

    53

    How to Use SELF 3.0 How to Debug SELF Programs

    Attaching a process with an error sets the debuggers current activation to the bottommost interest-

    ing activation. In this case, the current activation is number 6. Activations 0 to 5 are omitted by the

    debugger since they are part of the error handling mechanism itself. By issuing the commands upand down the current activation can be changed to expose other stack activations.

    The current byte code position of the activation is highlighted by underlining part of the source

    code. The highlighting shows the message being sent when the error occurred. Both the receiver

    and the selector are underlined. If your terminal does not support underlining, highlighting is

    shown by surrounding the expression with curly brackets ({}).

    In this example, the highlighting shows that the message i is being sent to a block object. This ex-plains the problem: the expression needed a period after the block to separate the expression into

    two statements.

    16.2 Setting Breakpoints

    Breakpoints can be added to a program by inserting halt statements (assuming that the receiver

    inherits from defaultBehavior). When a halt statement is executed, the currently executingprocess is suspended with a message indicating that a halt has occurred. The user can then examine

    the stack and control the execution of that process. Lets single step a typed in expression by set-

    ting a breakpoint as the first statement:

    Self 3> halt. 6 printLineHalt: running process: halt. 6 printLine)To debug this process, type "attach: 26"

    Self 4> attach: 7 attach to the process with history number 7Process has been attached to the debugger.shell = (halt. 6 printLine)

    the current byte code position is haltProcess , suspended, activation: 5 in [0,5].File:

    Self 5> step single stepshell = (halt. 6 printLine)Process , suspended, activation:0 in [0,0].File:

    ... etc ...

    As shown, breakpoints are explicitly inserted in the source code. Setting a breakpoint in a method

    can be done through the ui using the edit slotor edit code slot menu options..

    Caution: inserting halt in a method used by the core system can result in unexpected behavior(e.g., the debugger itself might break). This problem can be solved by using conditional break-

  • 7/28/2019 How to Use SELF 3.0

    54/62

  • 7/28/2019 How to Use SELF 3.0

    55/62

    55

    How to Use SELF 3.0 How to Debug SELF Programs

    16.4 Summary of Debugger Commands

    The following table summarizes the debugger commands.

    16.5 The Well-Known printLine Technique

    A simple and yet powerful way to monitor the program execution is to insert print statements in

    the methods you wish to observe. The messages print: and printLine: sent to transcript

    with a string as argument print the string in a transcript window (similar to a typein).

    16.6 When All Else Fails Tracing Message Sends

    The system contains a rudimentary mechanism to trace the execution of a SELF program. This

    tracing facility is not commonly used, however, because in general it generates too much informa-

    a. A bytecode is trivial if it is a push of a literal or a send to a slot residing in

    the lexical scope of the current activation.

    Command Description

    attach attach the process that most recently generated an error

    attach: n attach the process with object reference number n

    detach detach the debugged process

    step[:n] execute (n) non trivial bytecodesa

    stepi[:n] execute (n) bytecodes

    next[:n] execute (n) non trivial bytecodes in the current activation

    nexti[:n] execute (n) bytecodes in the current activation

    finish finish executing the current activation

    cont continue execution

    trace print out a stack trace of the process

    show display the current activation

    show: n go to and display the nth activation on the stack

    status display the status of the debugged process

    up[: n] go up (n) activation(s)

    upLex go up to the lexical enclosing scope of this activation

    down[: n] go down (n) activation(s)

    lookup: lookup the given name in the context of the current activation

  • 7/28/2019 How to Use SELF 3.0

    56/62

    56

    How to Use SELF 3.0 How to Save SELF Objects in the World as Source Files

    tion to be useful (it was develope