Objective-Everything Release 5.  Copyright ©1994-1998 by TipTop Software, Inc.  All Rights Reserved.

 Quick Tour

1. Run ObjTcl

In ObjShell: Double-click on ObjShell.app.  Click "Load Tcl", and then click "Tcl".

In a terminal shell: Type objtclsh.

To run the application kit type appkit::run.  To open an Interactor window, click Objective->Interact->Interactor, and select "Tcl".  [This does not work in Windows, due to Windows limitations.  In Windows, you have to run ObjShell.app.]

In InterfaceBuilder: Load ObjPalette.palette from /Local/Developer/Palettes/. Click Tools->Objective->Interactor->Interact and select Tcl to open an ObjTcl interactor window.

All of the following examples are executed in InterfaceBuilder.

NOTE: If you get a Tcl error, you can type "set errorInfo" in an interactor to get the error details.

2. Invoke a C function

Type a function name followed by the arguments.  E.g., in an Interactor window, type:

 NSRunAlertPanel "Tcl" "Hello World!" [nil] [nil] [nil] 
 [fun {void ()(char *fmt, ...)} printf] "Hello %s!\n" "World" 

(The printf output appears in the console window.)

3. Access a C global

To read a value, simply "call" it by name, or simply access it as a Tcl global variable:

tcl% puts "argc: $NSArgc, argv: [$NSArgv]" 
argc: 1, argv: /NextDeveloper/Apps/InterfaceBuilder.app/InterfaceBuilder 
# Define global NSGenericException, and then access it 
# (it is a string with contents "NSGenericException") 
tcl% defglob NSGenericException [ptr {NSString*} NSGenericException] 
tcl% puts $NSGenericException 
NSGenericException

# Alternate: define global NSRangeException, and then access it 
tcl% cdef { NSString *NSRangeException; } 
tcl% puts [NSRangeException] 
NSRangeException 

4. Send a message

Use ObjC-style syntax to send a message.  Make sure that you have a space after each colon ':'.

tcl% [NSApp] class 
IB 
tcl% $NSApp showInfoPanel: [nil] 

tcl% set x [[NSObject alloc] init] 
@NSObject@... 
tcl% $x autorelease 
# ObjTcl automatically takes care of memory management. 
# In this example, when you (auto)release the object, it is not yet deallocated, 
# since the Tcl variable x holds a reference to the object. 
tcl% $x description 
<NSObject: 0x...> 
tcl% * $x 
<NSObject: 0x...> 
tcl% unset x 
# The object is now really gone.

# ObjTcl also detects when objects become illegal. 
tcl% set x [[NSObject alloc] init] 
@NSObject@... 
tcl% $x release 
tcl% $x release 
tcl% $x description 
receiver is illegal object: "@NSObject@..." 

5. Extend a class

Simply define a category on a class.

tcl% category NSObject { 
%-->   method -(void)sayHelloTo:(NSString*)name { 
%-->     NSRunAlertPanel "Tcl" "Hello $name" [nil] [nil] [nil] 
%-->   } 
%--> } 
NSObject 
tcl% $NSApp sayHelloTo: [NSFullUserName] 

You can use "extend" as a synonym for "category".

6. Define a class

Classes are defined using the "class" command.  Instance variables and method prototypes are specified using the ObjC syntax.

tcl% class MyObject NSObject { 
%-->   NSString *aString; 
%-->   id anObject; 
%-->   char *aCString; 
%--> } { 
%-->   method -(void)dealloc { 
%-->     set aString [nil]   ; # release aString 
%-->     set anObject [nil]  ; # release anObject 
%-->     set aCString [NULL] ; # free aCString 
%-->     super dealloc 
%-->   } 
%--> 
%-->   method -(void)setStringValue:(NSString*)s { 
%-->     puts "$self $_cmd $s" 
%-->     set aString $s 
%-->   } 
%--> 
%-->   method -(NSString*)stringValue { 
%-->     puts "$self $_cmd" 
%-->     return $aString 
%-->   } 
%--> 
%-->   # etc. 
%--> } 
MyObject 
tcl% set obj [MyObject object] 
@MyObject@a9ab4 
tcl% $obj setStringValue: "Hello World!" 
@MyObject@a9ab4 setStringValue: Hello World! 
tcl% $obj stringValue 
@MyObject@a9ab4 stringValue 
Hello World! 
tcl% fetch $obj 
MyObject {Hello World!} nil {} 
tcl% unset obj 
@MyObject@a9ab4 dealloc 

Note: The effect of class declaration is equivalent to defining a class without any methods, and then defining the methods in a category..

7. Extend an instance

Objective-Everything lets you define instance-specific instance methods.

tcl% set x [MyObject object] 
@MyObject@448ab0 
tcl% set y [MyObject object] 
@MyObject@4456d4 
tcl% category $x { 
 %-->   method -(const char*)sayHello { 
 %-->     return "Hello from $self" 
 %-->   } 
 %--> } 
 @MyObject@448ab0 
tcl% $x sayHello 
Hello from @MyObject@448ab0 
tcl% $y sayHello 
<MyObject:0x4456d4> does not respond to sayHello ... 
tcl% $x class 
MyObject 
tcl% $y class 
MyObject

# Override -showInfoPanel: of $NSApp. 
# First, find out what the -showInfoPanel: prototype is 
tcl% unparse $NSApp 
@interface IB : NSApplication <IB_Full> 
// Subclasses: None 
{ 
  ... 
}

... 
- (void)showInfoPanel:(id)a0; 
... 
@end

# Or, simply: 
tcl% objtcl::info methods [$NSApp class] showInfo* 
- (void)showInfoPanel:(id)a0; 
# Now, override -showInfoPanel: to run an alert panel, and then
invoke 
# the previous (in this case ObjC) method implementation. 
tcl% set NSApp 
@IB@12e430 
tcl% extend $NSApp { 
%-->   method -(void)showInfoPanel:(id)sender { 
%-->     NSRunAlertPanel "Tcl" "About to show IB info panel" [nil] [nil] [nil] 
%-->     ex showInfoPanel: $sender 
%-->   } 
%--> } 
@IB@12e430 

Now, click Info->InfoPanel.

8. Create a NIB file

Click Document->NewApplication.  Drag the ObjTcl interpreter object from ObjTcl palette into the object suitcase. Drag a button into the window.  Ctrl-connect the button to the interpreter object, and select the newWInteractor: action.

Now, when you run the nib file by clicking Document->TestInterface, when you click the button, you will get an interactor window in which you can type commands to be executed by the interpreter.

9. Connect a global variable

Add another button into the window.  Ctrl-drag from the interpreter instance to this button.  Type "but" in the connections inspector.  Ctrl-drag from the interpreter instance to the "My Window" window title bar.  Type "win".

Run the interface (Cmd-r or click Document->TestInterface).  Hit the button which opens the interactor window. Type:

tcl% $but setTitle: "Hello" 
tcl% $win setTitle: "World" 

Quit the TestInterface mode.  Close the nib file (save it if you like).

10. Use the Code object to implement simple actions

In this example we build a simple expression calculator which simply uses the Tcl expr command to evaluate mathematical expressions.

Click Document->NewApplication.  Drag the TextField object into window "My Window".  Change it to look something like:

Drag the Code object from ObjPalette into the object suitcase.  Ctrl-Alt-drag from the code object to the result field.  Type "resultField". In the implementation inspector, select Tcl, hit "+", and implement action as follows:

extend $self {
  method - (void)action:(id)sender {
    set r [expr [$sender stringValue]] 
    [xvarset $self resultField] setStringValue: $r 
  }
}

Ctrl-drag from the "Expr:" field to the code object, and connect it to the "action:" action.
Test the interface:  Type "1+2" and hit Return.  Type "sin(1)" and hit Return.

Close the nib file (save it if you like).

The Code object lets you implement interpreted action methods without having to implement a new class.  In general, the Code object is useful for implementing simple actions.

11. Define actions in interpreter startup code

Another way of implementing actions is to directly extend an instance with an action method.  In this example we implement the same calculator as in the previous example.

Create a window with the fields, like in the previous example.

Drag an ObjTcl interpreter instance from the ObjTcl palette into the object suitcase.  Connect fields as globals in the interpreter with names "rfield" and "efield" (Ctrl-drag from the interpreter to each field, and type the field name).

Since we want to define an action for "efield", double-click on the "efield" in the ConnectionInspector.  Click "Create" when you are asked whether to create action implementation.

Implement the action as follows:

 extend $efield { 
   method -(void)action:(id)sender { 
     global rfield 
     $rfield setStringValue: [expr [$self stringValue]] 
   } 
 } 

Run and test the interface.

Now, add some error handling:

 extend $efield { 
   method -(void)action:(id)sender { 
     global rfield 
     if [catch {expr [$self stringValue]} r] { 
       NSRunAlertPanel "Error!" "$r" [nil] [nil] [nil] 
     } 
     $rfield setStringValue: $r 
     [$self controlView] selectText: [nil] 
   } 
 } 

Note: You should not define a class in a NIB file (in interpreter startup code, or in a code object) if the NIB file contains an instance of that class, because it is not possible to ensure that the code is executed before the instance is instantiated.

12. Extend an object to perform an action

Yet another way of implementing actions is to directly extend an instance with an action method.  In this example we implement the same calculator as in the previous example.

Create a window with the fields, like in the previous example.

Double-click on the "Expr:" field to select it.  Connect xvar "resultField" of the "Expr:" field to the "Result:" field: Ctrl-Alt-Drag from the "Expr:" filed to the "Result:" field, type "resultField", and hit Return.

Since we want to define an action for the "Expr:" field, double-click on the "Expr:" field to select it. In the Implementation inspector select "Tcl", hit "+", and implement the action as follows:

extend $self {
  method - (void)action:(id)sender {
    set r [expr [$sender stringValue]] 
    [xvarset $self resultField] setStringValue: $r 
  }
}

Run and test the interface.

13. Connect to a remote interpreter

In a terminal shell, type:

 robjtclsh IBInterp 

This will give you access to the default ObjTcl interpreter in InterfaceBuilder.  You can now issue any command to this interpreter; e.g., type: $NSApp showInfoPanel: [nil]

To set a remote interpreter connection in InterfaceBuilder:  Drag an Interactor object from the ObjPalette into the object suitcase.  Drag a button into the window.  Connect a button to the interactor, so that it sends the "run:" message. In the attribute inspector for the interactor, click the Remote switch, so that it is ON, enter "IBInterp" into the connection field, enter "ObjTclInterp" into the interpreter field, and hit return.   Now when you run the nib file, and hit the button, the interactor will connect to IB (itself)...

14. Run Objective-Browser

Type "browse $NSApp" in an interactor window, and browse away!

To run the browser from a Terminal shell:

 appkit::run { browse $NSApp } 

15. Create a standalone application

Use ProjectBuilder to create an application project, and use InterfaceBuilder to create nib files.  Make sure that you link the application with ObjCore and ObjAppKit frameworks.  When you build and run the application, Objective-Everything will get initialized...

Note: Under Windows, you need to reference a symbol in each of the frameworks that you link with.  E.g., in YourApp_main.m, make sure you do:

 #import <ObjAppKit/ObjAppKit.h> 
 int main(int argc, const char *argv[]) { 
 { 
   [TTInterp class]; 
   [TTApplication class]; 
   return NSApplicationMain(argc, argv); 
 } 

See UsingPB.rtfd for how to include ObjTcl files in the project, how to manage and edit them using PB.

If you have a NIB file which you want to run as an application, you can simply run objtclsh, and type:

 appkit::run -nib /your/nib/file.nib 

16. Embed Objective-Everything into your application

Statically link your application with the ObjCore and ObjAppKit frameworks; or, dynamically load these frameworks:

 [[NSBundle bundleWithPath:@"/LocalLibrary/Frameworks/ObjAppKit.framework"] 
   principalClass]; 

To open an interactor window:

 [TTInterp newWInteractor:nil]; 

or, send the newWInteractor: message to the first responder, e.g., via a button, or a menu item.   This will give you a starting point for interactively issuing commands to your app...

17. Run an application with Objective-Everything preloaded

For example, to run Objective-Browser inside EOModeler:

objmeddle /System/Developer/Applications/EOModeller.app/EOModeler

You can now run an interactor from the Objective menu (in Tools), or run ObjBrowser, etc.

18. Read the documentation

Read the documents in ObjCore/Documentation/Concepts to become familiar with the general Objective-Everything concepts.  Read other documents in this directory to get familiar with ObjTcl.

Also, make sure that you look at the examples which are included in each Obj<Lang>.framework/Resources/Examples directory.


[previous][contents][next]