是否需要使用模块从项目根目录开始的路径?

时间:2019-03-11 15:25:23

标签: racket

我正在制作一个Web应用程序。考虑这样的结构

ProjectName/racket/Servlet.rkt
ProjectName/racket/chart/barchart/BarChart.rkt
ProjectName/template/barchart.svg

如何在BarChart.rkt模块内部使用Barchart.svg模板而不使用任何..?理想情况下,如果从ProjectName(即cd ProjectName; racket racket/Servlet.rkt)启动应用程序,则require部分类似于(require "template/barchart.svg"),但使用ProjectName作为根目录,而不是相对的ProjectName / racket / barchart。

1 个答案:

答案 0 :(得分:3)

1)天真的方法

您可以使用(define-runtime-path)

项目名称/图表/barchart/BarChart.rkt:

#lang racket/base
(provide barchart-template)
(require
  racket/runtime-path
  racket/file)

(define-runtime-path barchart.svg "../../template/barchart.svg")

(define (barchart-template)
  (file->string barchart.svg))

ProjectName / Servlet.rkt:

#lang racket/base
(require ProjectName/chart/barchart/Barchart)

(displayln (barchart-template)) ;; prints the content of the SVG file, wherever you are

2)更好的方法

注册您的包裹

根据我的经验,开发Racket应用程序时处理路径的最佳方法是制作一个程序包,然后使用经典的(require my-package/my-module)语法而不是使用相对路径。

例如,如果您有一个像这样的项目:

ProjectName/Servlet.rkt
ProjectName/chart/barchart/BarChart.rkt
ProjectName/template/barchart.svg

通过在项目的根目录添加info.rkt文件,将其转换为一个包。

echo "#lang info" > ProjectName/info.rkt

然后致电cd ProjectName; raco pkg install

然后,您可以在带有(require ProjectName/chart/BarChart)的任何文件中要求BarChart.rkt。

为什么我要告诉你这一切?因为现在,您可以从任何文件夹启动应用程序:

racket -l ProjectName/Servlet

无论运行程序的目录是什么,这将使您轻松测试路径是否得到处理。

摆脱../..

现在,您的软件包已在本地数据库中注册,您可以使用(pkg-directory)中的pkg/lib轻松找到它的根目录:

项目名称/图表/barchart/BarChart.rkt:

#lang racket/base
(provide barchart-template)
(require
  racket/file
  pkg/lib)

(define (barchart-template)
  (define template.svg (build-path (pkg-directory "ProjectName")
                                   "template/barchart.svg"))
  (file->string template.svg))