簡體   English   中英

Scala:如何在repl中安裝廣泛的軟件包系統?

[英]Scala: How can I install a package system wide for working with in the repl?

在Python中,如果我使用pip install package_name安裝包,我可以通過鍵入python打開Python repl,只需按名稱導入包,無論我目前在文件系統中的目錄是什么。

像這樣

$ python
Python 2.7.3 (default, Sep 26 2013, 20:03:06) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> 

並導入requests庫,我可以在repl中使用它。

在Scala中,我知道如何在使用sbt的項目中執行此sbt ,但出於學習目的,我想以這樣的方式安裝包,以便我可以在命令行中鍵入scala ,然后導入已安裝的包,不依賴於特定項目。

$ scala
Welcome to Scala version 2.10.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_40).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scalaz._
<console>:7: error: not found: value scalaz
       import scalaz._

我怎樣才能做到這一點?

Scala與Python不同。 為Scala 2.9.x編譯的代碼與2.10.x不兼容。 因此,如果您使用不同的版本,全局定義可能會導致很多問題。

您可以使用SBT並添加到$ HOME / .sbt / plugins / build.sbt

libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.0.4"

要么

libraryDependencies += "org.scalaz" % "scalaz-core_2.10" % "7.0.4"

然后轉到/ tmp並使用SBT啟動Scala REPL:

sbt console

但從長遠來看,這不是一個好主意。

最好的辦法是安裝SBT,創建一個build.sbt文件並將其放入其中:

libraryDependencies += "org.scalaz" % "scalaz-core_2.10" % "7.0.4"

scalaVersion := "2.10.2" 

initialCommands in console := "import scalaz._, Scalaz._"

現在將控制台更改為build.sbt文件夾並運行

sbt console

有了這個,您可以嘗試使用REPL並已導入scalaz並在類路徑中。 此外,還可以輕松添加其他依賴項。 SBT很酷,你不需要手動安裝新的Scala版本,只需在build.sbt中聲明它。

通常不推薦這樣做,因為大多數jar庫都與程序員項目一起使用。 此外,與其他生態系統不同,jar庫通常通過一些用戶模式庫管理工具(如ivymavensbt ,正如您可能已經觀察到的那樣。

如果您真的想這樣做,可以將jar安裝到scala的TOOL_CLASSPATH位置,您可以從scala.batscala shell腳本文件中找到TOOL_CLASSPATH位置以及scala發行版。 或者,您可以構建自己的自定義scala repl,它可以從某個已配置的位置加載全局可安裝的庫。 無論哪種方式,它都需要使用TOOL_CLASSPATH

PS:我目前還沒有進入實際 scala.bat文件來幫助你,但你可以看看它 在這里 ,並 在這里明白了我的意思。 請注意,這些文件可能不會顯示.bat文件的結構如何與分發中的文件一樣(並且可能過時)。 請在官方發行版中查閱以獲取相關信息。

編輯

我現在可以解釋一下,我回來看看官方發行版中包含的實際 scala批處理和shell腳本:-)

就像我上面說的那樣, scala腳本加載了TOOL_CLASSPATH文件夾中的所有jar文件,該文件夾通常是${SCALA_HOME}/lib 它還提供了使用有前途的-toolcp選項添加到TOOL_CLASSPATH-toolcp - 讓我們看看它顯示的內容:(批處理腳本類似 - 我只是從scala shell腳本中顯示內容)

while [[ $# -gt 0 ]]; do
  case "$1" in
    -D*)
      # pass to scala as well: otherwise we lose it sometimes when we
      # need it, e.g. communicating with a server compiler.
      java_args=("${java_args[@]}" "$1")
      scala_args=("${scala_args[@]}" "$1")
      shift
      ;;
    -J*)
      # as with -D, pass to scala even though it will almost
      # never be used.
      java_args=("${java_args[@]}" "${1:2}")
      scala_args=("${scala_args[@]}" "$1")
      shift
      ;;
    -toolcp)
      TOOL_CLASSPATH="${TOOL_CLASSPATH}${SEP}${2}"
      shift 2
      ;;
    -nobootcp)
      unset usebootcp
      shift
      ;;
    -usebootcp)
      usebootcp="true"
      shift
      ;;
    -debug)
      SCALA_RUNNER_DEBUG=1
      shift
      ;;
    *)
      scala_args=("${scala_args[@]}" "$1")
      shift
      ;;
  esac
done

正如您所看到的,這是非常有限的 - 您必須指定要添加的每個 jar。 你可以使用-cp 我們可以做得更好嗎? 當然,我們必須在這個toolcp業務中toolcp

addtoToolCP() {
    for i in $(find $1 -name "*.jar")
    do
        if [[ -z "$TOOLCP" ]]
        then
            TOOLCP="$i"
        else
            TOOLCP="${TOOLCP}:$i"
        fi
    done
}

因此,您可以檢查TOOLCP參數的空白,並相應地調用scala作為scala -toolcp $TOOLCP如果它非空)。 現在,您可以調用shell腳本: myscalascript <list-of-paths-to-be-added-to-toolcp> 或者您可以保留一個文件夾,然后繼續向該文件夾添加新庫。 希望這有助於 - 正如其他人所說的那樣, 注意二進制兼容性問題 二進制不兼容問題只會影響主要的scala版本,次要版本應該完全兼容。 最后,冒着重復自己死亡的風險, 只有在你確定要這個時才使用它。 :-)

除了SRI我還使用以下解決方案,shell腳本:

/usr/bin/scalaz

    #!/bin/sh
    scala -cp  ~/.ivy2/cache/org.scalaz/scalaz-core_2.10/bundles/scalaz-core_2.10-7.1.0-M3.jar ... other libs

然后在終端中調用它:

$ scalaz
Welcome to Scala version 2.10.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_40).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import scalaz._; import Scalaz._
import scalaz._
import Scalaz._

scala> Monad[Option].point(1)
res0: Option[Int] = Some(1)

scala>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM