3
votes

I am coming from Java and Python, and am having difficulty understanding how object-oriented code works in Racket.

  1. Given

    (define food%
     (class object%
        (super-new)
        (init-field name)
        (field (edible? #t))
        (init-field healthy?)
        (init-field tasty?) ) )
    

    define a superclass fruit% of food% which always has the healthy? value of #t, and which doesn't require one to set the healthy? field when defining a new fruit.

  2. In racket/gui, define a super-class of button% called text-input-button% which has two new fields, output (ideally of type text-field%) and text (ideally a string), and whose callback field has as its value a function which appends the value of the text field to the current contents of the value of the output field. Practically, the buttons would input characters into the text-field specified.

I think if I can see these two examples, a large amount of my confusion will be resolved. That being said, I am looking for the 'proper' or textbook means of doing this, rather than some round-about trick using set!, unless that is all the proper method boils down to.

1

1 Answers

4
votes

(1) Did you really mean fruit% should be a superclass of food%? It seems to me like you'd want fruit% to be a subclass. Here it is assuming it's a subclass:

(define fruit%
  (class food%
    (super-new [healthy? #t])))

(2) For this, I think it's best if you create a new widget based on a panel% to store the two sub-widgets:

(define text-input-button%
  (class horizontal-panel%
    (super-new)
    (init-field text)
    ;; callback for the button
    (define (callback button event)
      (define new-value (string-append (send output get-value) text))
      (send output set-value new-value))
    (define button (new button% [label "Click me"]
                                [parent this]
                                [callback callback]))
    (define output (new text-field% [label "Output"]
                                    [parent this]))))

;; testing it out
(define f (new frame% [label "Test"]))
(define tib (new text-input-button% [text "foo"] [parent f]))
(send f show #t)

If you really want to make it a subclass of button%, you could, but I think this is cleaner.