So that is the defined behavior, module code is to run only once
independent of the shape of the require tree?

Yeah, that output shown above is coming from the program, cut from the
transcript, so I'm scratching my head as to how the module code is running
more than once.  I'll stub down the actual code...  ah I have an idea!
Maybe in some cut and paste jobs I made more than one copy of it ... hmmm

On Wed, Sep 23, 2015 at 7:44 PM, Robby Findler <[email protected]>
wrote:

> The top-level code in the module runs only once. Here's a small
> version of your code and the results of running it.
>
> ☕  cat A.rkt
> #lang racket
> (require  "utility.rkt")
> (printf "A\n")
> ☕  [robby@gongguan] ~/x
> ☕  cat B.rkt
> #lang racket
> (require  "utility.rkt")
> (printf "B\n")
> ☕  [robby@gongguan] ~/x
> ☕  cat C.rkt
> #lang racket
> (require "A.rkt")
> (require "B.rkt")
> (printf "C\n")
> ☕  [robby@gongguan] ~/x
> ☕  cat utility.rkt
> #lang racket
> (printf "utility\n")
> ☕  [robby@gongguan] ~/x
> ☕  racket
> Welcome to Racket v6.2.900.17.
> -> (enter! "C.rkt")
> utility
> A
> B
> C
> "C.rkt">
>
>
>
>
> On Wed, Sep 23, 2015 at 3:46 AM, Thomas Lynch
> <[email protected]> wrote:
> >
> > There is a module that is utilitarian in nature, that is included in
> another
> > other modules.   These other modules are in turn included in yet other
> > modules.
> >
> > module A:
> >
> >     #lang racket
> >      (require  "utility.rkt")
> >
> >
> > module B:
> >
> >      #lang racket
> >      (require "utility.rkt")
> >
> >
> > module C:
> >
> >      #lang racket
> >      (require "A.rkt")
> >      (require "B.rkt")
> >
> >
> > 'utility' has some initialization code and a module variable that is
> > intended to be shared by the utility code.  Say for the sake of example,
> > utility maintains a collection of test functions:
> >
> > (define test-routines '())
> > (define (test-name a-test) (symbol->string (object-name a-test)))
> >
> > (define (test-hook a-test)
> > (display "hooking test: ") (displayln (test-name a-test))
> > (set! test-routines (cons a-test (remove a-test test-routines (λ(e f)
> > (string=? (test-name e) (test-name f)))))))
> >
> >
> > (define (test-all)
> >     (let*(
> >           [results (map test (reverse test-routines))]
> >           [no-tests (length results)]
> >           [result-flags (map cadr results)]
> >           [error-count (count (λ(e) (not e)) result-flags)]
> >           [all-passed (andmap (λ(e) e) result-flags)]
> >           )
> >       ;;(displayln results)
> >       (cond
> >         [all-passed (display "all ")(display no-tests) (displayln "
> > passed")]
> >         [else
> >           (display "failed: ")
> >           (display error-count)
> >           (display " of ")
> >           (displayln no-tests)
> >           ]
> >         )
> >       all-passed
> >       ))
> >
> >
> > So what is happening here is that the module code initializes a global
> test
> > list.  Other modules which require utilities.rkt  then call  test-hook to
> > hook in their test code.  Then after all the modules are loaded, the
> > application calls  (test-all)  to see that everything is running well.
> >
> > However, it isn't working because the "utility.rkt" module initialization
> > code is running multiple times, and each time clobbering (making new
> > version?) of the test list.   This behavior did not occur when the
> require
> > call depth was only one deep, but now that it is two deep, it is
> happening.
> >
> > racket@> (enter! "object.rkt")
> > hooking test: example-pass-test
> >
> > ...
> > (test-all) to run the tests
> > hooking test: and-form-test-0
> > hooking test: test-Λ-0
> > ...
> >
> > ===>  RUNNING INIT CODE IN MODULE A SECOND TIME:
> >
> > hooking test: example-pass-test
> > ...
> > hooking test: test-flatten-1
> > hooking test: test-replace-0
> >
> >          ....
> > ===>  RUNNING INIT CODE IN MODULE A THIRD TIME:
> >
> > hooking test: example-pass-test
> > hooking test: example-fail-test
> > ....
> >
> >
> > Should it be like this?   Is a module static (one copy)  or is it like a
> > class (new copy on invocation)  actually I'm seeing a third behavior,
> static
> > at one level deep, new instances at two levels deep (or just running the
> > code again over the same instance?)
> >
> >
> >
> >
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Racket Developers" group.
> > To unsubscribe from this group and stop receiving emails from it, send an
> > email to [email protected].
> > To post to this group, send email to [email protected].
> > To view this discussion on the web visit
> >
> https://groups.google.com/d/msgid/racket-dev/421e6cbe-e3f4-4164-8cff-db74187bd986%40googlegroups.com
> .
> > For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-dev/CAGxFmCNw%2BbJJ-76XxNoC48dL4fQxp%3DfE75%3DTjB-zD%2BX5udNuPg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to