guile வலை வழங்கியை இயங்கிக்கொண்டிருக்கும்போதே REPL மூலம் மாற்றியமைப்பது

guile வலை வழங்கியை இயங்கிக்கொண்டிருக்கும்போதே REPL மூலம் மாற்றியமைப்பது

Published by Arun Isaac on

In other languages: English

Tags: lisp, scheme, மென்பொருள்

guile வலை வழங்கியை இயங்கிக்கொண்டிருக்கும்போதே REPL மூலம் மாற்றியமைப்பது எப்படி?

இயங்கிக்கொண்டிருக்கும் வழங்கிகளை முடக்காமலேயே அவற்றின் நிரலை REPL மூலம் மாற்றியமைப்பது lisp மொழிகளின் தனிச் சிறப்பு. ஆனால் இதை scheme மொழியில், குறிப்பாக guile மொழியில், செய்வது சற்று சிக்கலானது. இதை நான் எவ்வாறு செய்கிறேன் என விளக்குகிறேன். இது நல்ல வழியாவென அறியேன். வேறு நல்ல வழியறிந்தால் கண்டிப்பாக மின்மடல் அனுப்புக.

முதலில் guile மொழியில் localhost:8080 பொருந்துவாயில் காத்திருக்கும் எளிய வலை வழங்கியொன்று.

(use-modules (web server))

(define (handler request request-body)
  (values '((content-type . (text/plain)))
          "Hello World!\n"))

(run-server handler)
$ curl http://localhost:8080
Hello World!

இதனுடன் /tmp/guile Unix பொருந்துவாயில் (Unix socket) REPL வழங்கியொன்றை இன்னொரு இணை இழையாக (parallel thread) அமைப்போம்.

(use-modules (system repl server)
             (web server))

(define (handler request request-body)
  (values '((content-type . (text/plain)))
          "Hello World!"))

(spawn-server (make-unix-domain-server-socket
               #:path "/tmp/guile"))
(run-server handler)

Emacs பயன்படுத்தினால் இதனுடன் M-x geiser-connect-local /tmp/guile கொண்டு இணையலாம். இப்போது handler செயலாற்றியை மாற்றி geiser REPL மூலம் நிறுவினாலும் வலை வழங்கியின் வெளியீடு மாறாது. ஏன்? ஏனென்றால் run-server செயலாற்றி handler செயலாற்றியின் மதிப்பை (value) மட்டுமே பெறுகிறது. handler செயலாற்றி மாறினாலும் run-server பழைய handler செயலாற்றியையே கவ்வியிருக்கிறது.

இதைத் தவிர்க்க என் செய்யலாம்? நிரல்கூறு அகங்காணல் (module introspection) பொறியைப் பயன்படுத்தி ஒவ்வொரு முறையும் 'handler என்னும் பெயர் சுட்டும் செயலாற்றியைக் கண்டறியுமாறு ஒருப் பெயரற்ற lambda செயலாற்றியை run-server கண் அளிக்கலாம். இப்போது handler செயலாற்றியை மாற்றினால் வலை வழங்கியின் வெளியீடும் சரியாக மாறும்.

(run-server (lambda (request body)
              ((module-ref (current-module)
                            'handler)
               request body)))

handler செயலாற்றி வேறு நிரல்கூறில் இருப்பின் அதைப் பின்வருமாறு பெறலாம்.

(run-server (lambda (request body)
              ((module-ref (resolve-module '(my-project web-server-module))
                            'handler)
               request body)))