Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

Using NetRexx


NetRexx is a programming language designed as an alternative to Java. The idea behind NetRexx, which was created by IBM Fellow M.F. Cowlishaw (who also designed Rexx), is to make programming the Java Virtual Machine (JVM) easier than with Java. Although NetRexx syntax is derived from Rexx, NetRexx is strongly typed, making it first-rate for programming the JVM and allowing access to primitive (binary) datatypes. NetRexx compiles to Java bytecode, and NetRexx classes and Java classes are equivalent. In short, when your development requirements include web programming or other applications for the JVM, you may well find it easier and more productive to program in NetRexx than Java.

NetRexx is freely available under IBM's Employee Written Software agreement and can be downloaded from http://www2.hursley.ibm.com/netrexx/ as either a ZIP file or a UNIX tar.Z file. It comes with instructions for installation and use, and also includes extensive documentation on the language definition and keyword instructions. Cowlishaw's book, The NetRexx Language (Prentice Hall, 1997), provides a complete reference.

Because NetRexx programs run on the JVM, they are fully portable and can be executed on any platform where Java is present. This includes Windows, OS/2, many flavors of UNIX, OS/390, and (soon) VM.

A NetRexx program contains the following:

  • The class instruction defines a new class, including the name of the parent class and any behaviors that it implements.
  • The properties instruction is optional; it defines class and instance variables. Properties may be public or private, so there may be more than one properties instruction in a class.
  • The method instruction identifies the beginning of a new method. There is no special syntax for the end of a method; a method ends when a new method begins.

As with Rexx, you don't need to declare variables before using them. NetRexx automatically determines the proper type of a variable from the context of its first use. Properties must be defined at the beginning of a class. Though it is not necessary to explicitly type them, it may be convenient to do so at this point. All other variables are local to the method that uses them.

Terms in NetRexx are evaluated in a simple and intuitive fashion that may be new to many programmers. NetRexx evaluates each term in the context in which it is first encountered. This allows new keywords to be added to the language without breaking existing programs. Simplified, the full search order is as follows:

  • A local variable or method argument?
  • A method in the current class?
  • A property in the current class?
  • A special word, such as this?
  • A data type?
  • If not, it must be a language keyword or instruction.

In Example 1, the select in the first line of the action method is recognized as a NetRexx keyword. However, if you insert select = 'blotz' at the beginning of that method, then the select appearing alone in a clause would have been detected as an error by the NetRexx compiler -- "unexpected use of local variable." Using select as a local variable in another method in the class would not preclude its recognition as a keyword in this method.

Example 1: The action method.

NetRexx also uses compound terms, which are evaluated from left to right as in Java. Thus, the term u.left(1) is the value of the term u, to which the NetRexx method left is applied with an argument of 1.

The Rexx Class

Recall that you don't have to declare variables in NetRexx. However, to be a first-class language for the JVM, NetRexx must be strongly typed. This can be largely transparent to the programmer, however, because NetRexx provides a default type for variables, the Rexx type, which is equivalent to the strings of the classic Rexx language. The NetRexx compiler automatically performs the necessary type conversion when translating a program to Java bytecodes.

Using variables of type Rexx significantly increases programmer productivity. You are freed from concern over the types of variables in a program, and the number of keystrokes required to type in the program is reduced.

The variables registered, u, p, and NameList in Listing One are all of type Rexx, but they came to this state from different directions:

  • The most common way to use a Rexx variable is to simply assign it a value and use it in your code (this is illustrated by the variable registered in the Valid method). Within the context of the program, registered is used as a Boolean, but there is no need to declare it as such.
  • u and p are Rexx variables that are assigned a value resulting from a Java method invocation (getText()) in the Register method; since the value returned by getText() is of type String, we explicitly cast this value to type Rexx before assigning it.
  • NameList is a private property that must be defined at the beginning of the class. Although I've declared a type here, it would be equally correct to simply list it as a property with no type or initial value.

Listing One

/* Registry.nrx  --  Applet for users to access private information */class Registry extends Applet        -- inherit from & extend the Applet class
properties private                   -- class and/or instance variables
  bclear = Button("  Clear  ")       -- Java Button class
  breg = Button("  Register  ")
  bacc = Button("  Access  ")
  name = TextField(15)               -- Java TextField class
  pw = TextField(15)
  statlbl = Label
  NameList = Rexx
method init                          -- initialization method
  LoadList                           -- initialize the names array
method start
  setLayout(BorderLayout())          -- our frame's layout (Java methods)
  setBackground(Color.white)
  setForeground(Color.blue)



  p1 = Panel()                       -- a different layout for the buttons
  p1.add(bclear)
  p1.add(breg)
  p1.add(bacc)
  add("Center", p1)



  stat = Panel()
  statlbl = Label(" ".copies(100), Label.CENTER)
  stat.setBackground(Color.white)
  stat.setForeground(Color.red)
  stat.setFont(Font("Helvetica", Font.BOLD+Font.ITALIC, 22))
  stat.add(statlbl)



  add("South", stat)                 -- add the panel to the frame



  p2 = Panel()                       -- a container for the "center" stuff
  p2.setLayout(BorderLayout())       -- but we want some control
  p2.setBackground(Color.blue)       -- set fg and bg colors for this area
  p2.setForeground(Color.white)



  p3 = Panel()                       -- one piece of the "center" stuff
  ulabel = Label("Enter Username:")  -- some label text
  name.setBackground(Color.white)    -- fg and bg colors for the text field
  name.setForeground(Color.black)
  p3.add(ulabel)                     -- populate this piece
  p3.add(name)



  p4 = Panel()                       -- another piece of the "center" stuff
  plabel = Label("Enter Password:")  -- some label text
  pw.setBackground(Color.white)      -- fg and bg colors for the text field
  pw.setForeground(Color.black)
  pw.setEchoCharacter(char "*")      -- echo character for sensitive data
  p4.add(plabel)                     -- populate this piece
  p4.add(pw)



  p2.add("North", p3)                -- now put the two pieces into the
  p2.add("South", p4)                --  "center stuff" container
  add("North", p2)                   -- and add that container to the frame



/* Handle an action (button press) */
method action(e=Event, o=Object) returns boolean
  select
     when e.target = bclear then do  -- if Clear button,
        name.setText('')             --   set contents of text fields
        pw.setText('')               --   to null
        statlbl.setText(String " ")  -- and clear message area
        return 1
        end

     when e.target = breg then do            -- if Register button,
        if Register then Status("RegOK")     -- and successful,
        return 1                             -- put up nice dialog
        end
     when e.target = bacc then do            -- if Access button,
        if Valid then AccessPrivate          --  if registered, let them in
           else Status("BadID")              -- otherwise, an error dialog
        return 1
        end
     otherwise return super.action(e, o)     -- other action we don't handle
     end



/* Sign up a new user */
method Register
  u = Rexx name.getText              -- get contents of text fields
  p = Rexx pw.getText
  if u = '' then do                  -- if username missing,
     Status("NOUSER")                --   put up message to tell them
     return 0                        --   that's a no-no; and return
     end                             --   failure
  if p = '' then do                  -- if password missing,
     Status("NOPW")                  --   put up message to tell them
     return 0                        --   that's a no-no; and return
     end                             --   failure
  NameList[u] = p                    -- otherwise, add to list
  return 1                           --   and return success



/* Validate the current user */
method Valid returns boolean
  u = Rexx name.getText
  if u = '' | u.left(1) = ' ' then return 0
  registered = 0
  loop thisname over NameList
     if u == thisname then do
       registered = 1
       leave
       end
     end
  if \registered then return 0
  p = Rexx pw.getText
  if NameList[u] \== p then return 0
  return 1



/* Put some initial users into the list */
method LoadList
  NameList = ''
  NameList['mickey'] = 'ClubLeader'
  NameList['minnie'] = 'mouseketeer'
  NameList['donald'] = 'aDuck'



/* Status Reporting */
method Status(reason='')
  select
     when reason = "RegOK"  then msg = "Registration Complete!"
     when reason = "NoUser" then msg = "Error:  Username Required"
     when reason = "NoPW"   then msg = "Error:  Password Required"
     when reason = "BadID"  then msg = "Error:  Userid and/or Password 
                                                       Missing or Invalid"
     otherwise msg = "Error: Unknown error; get help"
     end
  statlbl.setText(String msg)
method AccessPrivate
  statlbl.setText(string "Welcome to the Private Area")
  /*
     addr =          -- specify URL address here
     url = URL(addr)
     statlbl.setText(String url.getContent)
   */


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.