6.4 Field and Method Access

► |  | The Racket Reference

1 | Language Model
2 | Notation for Documentation
3 | Syntactic Forms
4 | Datatypes
5 | Structures
6 | Classes and Objects
7 | Units
8 | Contracts
9 | Pattern Matching
10 | Control Flow
11 | Concurrency and Parallelism
12 | Macros
13 | Input and Output
14 | Reflection and Security
15 | Operating System
16 | Memory Management
17 | Unsafe Operations
18 | Running Racket
| Bibliography
| Index

▼ | 6 | Classes and Objects

6.1 | Creating Interfaces
6.2 | Creating Classes
6.3 | Creating Objects
6.4 | Field and Method Access
6.5 | Mixins
6.6 | Traits
6.7 | Object and Class Contracts
6.8 | Object Equality and Hashing
6.9 | Object Serialization
6.10 | Object Printing
6.11 | Object, Class, and Interface Utilities
6.12 | Surrogates

► | 6.4 | Field and Method Access

6.4.1 | Methods
6.4.2 | Fields
6.4.3 | Generics

On this page:

6.4.1 Methods
send
send/ apply
send/ keyword-apply
dynamic-send
send*
send+
with-method
6.4.2 Fields
get-field
dynamic-get-field
set-field!
dynamic-set-field!
field-bound?
class-field-accessor
class-field-mutator
6.4.3 Generics
generic
send-generic
make-generic

Racket
top contents ← prev up next →

### 6.4 Field and Method Access🔗ℹ

In expressions within a class definition, the initialization variables, fields, and methods of the class are all part of the environment. Within a method body, only the fields and other methods of the class can be referenced; a reference to any other class-introduced identifier is a syntax error. Elsewhere within the class, all class-introduced identifiers are available, and fields and initialization variables can be mutated with set!.

#### 6.4.1 Methods🔗ℹ

Method names used within a class can only be used in the procedure position of an application expression; any other use is a syntax error.

To allow methods to be applied to lists of arguments, a method application can have the following form:

> > (method-id arg ... . arg-list-expr)

This form calls the method in a way analogous to (apply method-id arg ... arg-list-expr). The arg-list-expr must not be a parenthesized expression.

Methods are called from outside a class with the send, send/apply, and send/keyword-apply forms.

> syntax (send obj-expr method-id arg ...)
> (send obj-expr method-id arg ... . arg-list-expr)

Evaluates obj-expr to obtain an object, and calls the method with (external) name method-id on the object, providing the arg results as arguments. Each arg is as for #%app: either arg-expr or keyword arg-expr. In the second form, arg-list-expr cannot be a parenthesized expression.

If obj-expr does not produce an object, the exn:fail:contract exception is raised. If the object has no public method named method-id, the exn:fail:object exception is raised.

> syntax (send/apply obj-expr method-id arg ... arg-list-expr)

Like the dotted form of send, but arg-list-expr can be any expression.

> > syntax
> > (send/keyword-apply obj-expr method-id
> > keyword-list-expr value-list-expr
> > arg ... arg-list-expr)

Like send/apply, but with expressions for keyword and argument lists like keyword-apply.

> > procedure
> > (dynamic-send |  | obj |  |  |  |
> > |  | method-name |  |  |  |
> > |  | v ... |  |  |  |
> > |  | #:<kw> kw-arg ...) |  | → |  | any
> obj : object?
> method-name : symbol?
> v : any/c
> kw-arg : any/c

Calls the method on obj whose name matches method-name, passing along all given vs and kw-args.

> syntax (send* obj-expr msg ...+)
> msg |  | = |  | (method-id arg ...)
> |  | | |  | (method-id arg ... . arg-list-expr)

Calls multiple methods (in order) of the same object. Each msg corresponds to a use of send.

For example,

> (send* edit (begin-edit-sequence)
> (insert "Hello")
> (insert #\newline)
> (end-edit-sequence))

is the same as

> (let ([o edit])
> (send o begin-edit-sequence)
> (send o insert "Hello")
> (send o insert #\newline)
> (send o end-edit-sequence))

> syntax (send+ obj-expr msg ...)
> msg |  | = |  | (method-id arg ...)
> |  | | |  | (method-id arg ... . arg-list-expr)

Calls methods (in order) starting with the object produced by obj-expr. Each method call will be invoked on the result of the last method call, which is expected to be an object. Each msg corresponds to a use of send.

This is the functional analogue of send*.

Examples:

> (define point%
> (class object%
> (super-new)
> (init-field [x 0] [y 0])
> (define/public (move-x dx)
> (new this% [x (+ x dx)] [y y]))
> (define/public (move-y dy)
> (new this% [y (+ y dy)] [x x]))
> (define/public (get-pair)
> (cons x y))))
> > (send+ (new point%)
> (move-x 5)
> (move-y 7)
> (move-x 12)
> (get-pair))
> '(17 . 7)

> > syntax
> > (with-method ([id (obj-expr method-id)] ...)
> > body ...+)

Extracts methods from an object and binds a local name that can be applied directly (in the same way as declared methods within a class) for each method. Each obj-expr must produce an object, which must have a public method named by the corresponding method-id. The corresponding id is bound so that it can be applied directly (see Methods).

Example:

> (let ([s (new stack%)])
> (with-method ([push (s push!)]
> [pop (s pop!)])
> (push 10)
> (push 9)
> (pop)))

is the same as

> (let ([s (new stack%)])
> (send s push! 10)
> (send s push! 9)
> (send s pop!))

#### 6.4.2 Fields🔗ℹ

> syntax (get-field id obj-expr)

Extracts the field with (external) name id from the value of obj-expr.

If obj-expr does not produce an object, the exn:fail:contract exception is raised. If the object has no id field, the exn:fail:object exception is raised.

> procedure (dynamic-get-field field-name obj) → any/c
> field-name : symbol?
> obj : object?

Extracts the field from obj with the (external) name that matches field-name. If the object has no field matching field-name, the exn:fail:object exception is raised.

> syntax (set-field! id obj-expr expr)

Sets the field with (external) name id from the value of obj-expr to the value of expr.

If obj-expr does not produce an object, the exn:fail:contract exception is raised. If the object has no id field, the exn:fail:object exception is raised.

> procedure (dynamic-set-field! field-name obj v) → void?
> field-name : symbol?
> obj : object?
> v : any/c

Sets the field from obj with the (external) name that matches field-name to v. If the object has no field matching field-name, the exn:fail:object exception is raised.

> syntax (field-bound? id obj-expr)

Produces #t if the object result of obj-expr has a field with (external) name id, #f otherwise.

If obj-expr does not produce an object, the exn:fail:contract exception is raised.

> syntax (class-field-accessor class-expr field-id)

Returns an accessor procedure that takes an instance of the class produced by class-expr and returns the value of the object’s field with (external) name field-id.

If class-expr does not produce a class, the exn:fail:contract exception is raised. If the class has no field-id field, the exn:fail:object exception is raised.

> syntax (class-field-mutator class-expr field-id)

Returns a mutator procedure that takes an instance of the class produced by class-expr and a value, and sets the value of the object’s field with (external) name field-id to the given value. The result is #<void>.

If class-expr does not produce a class, the exn:fail:contract exception is raised. If the class has no field-id field, the exn:fail:object exception is raised.

#### 6.4.3 Generics🔗ℹ

A generic can be used instead of a method name to avoid the cost of relocating a method by name within a class, making method invocation more efficient.

Examples:

> (define woody%
> (class object%
> (define/public (draw who)
> (format "reach for the sky, ~a" who))
> (super-new)))
> (define gen-draw (generic woody% draw))
> (define (call-draw o)
> (send-generic o gen-draw "partner"))
> > (call-draw (new woody%))
> "reach for the sky, partner"
> (define woody2%
> (class woody%
> (define/override (draw who)
> (string-append (super draw who)
> "–there's a snake in my boot!"))
> (super-new)))
> > (call-draw (new woody2%))
> "reach for the sky, partner–there's a snake in my boot!"

> syntax (generic class-or-interface-expr id)

Produces a generic that works on instances of the class or interface produced by class-or-interface-expr (or an instance of a class/interface derived from class-or-interface) to call the method with (external) name id.

If class-or-interface-expr does not produce a class or interface, the exn:fail:contract exception is raised. If the resulting class or interface does not contain a method named id, the exn:fail:object exception is raised.

See the introduction to Generics for some examples.

> syntax (send-generic obj-expr generic-expr arg ...)
> (send-generic obj-expr generic-expr arg ... . arg-list-expr)

Calls a method of the object produced by obj-expr as indicated by the generic produced by generic-expr. Each arg is as for #%app: either arg-expr or keyword arg-expr. The second form is analogous to calling a procedure with apply, where arg-list-expr is not a parenthesized expression.

If obj-expr does not produce an object, or if generic-expr does not produce a generic, the exn:fail:contract exception is raised. If the result of obj-expr is not an instance of the class or interface encapsulated by the result of generic-expr, the exn:fail:object exception is raised.

See the introduction to Generics for some examples.

> procedure (make-generic type method-name) → generic?
> type : (or/c class? interface?)
> method-name : symbol?

Like the generic form, but as a procedure that accepts a symbolic method name.
top contents ← prev up next →