17
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

はじめに

私はElixirというプログラミング言語が好きです。
好きが高じて、autoracexというコミュニティを作りました。

海外からも参加してくださる方がいらっしゃいます。
そんな中のお一人、CamiloさんのElixirCL/wren-livebookを動かすことを楽しみます。

ElixirCL/wren-livebookは、wrenというプログラミング言語をLivebookの上でSmart cellを使って動かしちゃうというものです。

What is wren ?

私ははじめて知りました。

Wren is a small, fast, class-based concurrent scripting language
Think Smalltalk in a Lua-sized package with a dash of Erlang and wrapped up in a familiar, modern syntax.

なんだかスゴそう! 速そうです:rocket::rocket::rocket:

System.print("Hello, world!")

class Wren {
  flyTo(city) {
    System.print("Flying to %(city)")
  }
}

var adjectives = Fiber.new {
  ["small", "clean", "fast"].each {|word| Fiber.yield(word) }
}

while (!adjectives.isDone) System.print(adjectives.call())

動かしてみます

リポジトリのポイントは次の2点です。

  • Livebookで動かせる wren.livemd があります
  • bin/以下にwrenの実行コマンド(バイナリ)が入っています(電池付き :battery: )

Dockerを使います。

git clone https://github.com/ElixirCL/wren-livebook.git

cd wren-livebook

docker run -p 8080:8080 -p 8081:8081 --pull always -u $(id -u):$(id -g) -v $(pwd):/data livebook/livebook

ブラウザで、迷わずアクセスしてください。
Visit: http://0.0.0.0:8080/?token=mymb5cototlctb5osmvxrybirqfqwkcd

tokenの値は都度変わりますので、ターミナルに表示された通りの値を使ってください。

あとは、wren.livemdをOpenしてポチポチです。
@current @macos@current @unixに変更するのみで、Dockerコンテナ上で動きます。

動画を撮っておきました。

気づいたこと

すべてを理解したわけではありません。
私の関心がおもむいたところを3点紹介しておきます。

  • ①独自Smart Cell
  • #{Wren.path()} #{path}
  • trap "rm -f #{path}" 0 2 3 15

①独自Smart Cell

独自にSmart Cellが作れるようです。
詳しくはよくわかっていませんが、関係ありそうなところを https://raw.githubusercontent.com/ElixirCL/wren-livebook/main/wren.livemd から抜き出しておきます。

defmodule KinoGuide.WrenCell do
  use Kino.JS
  use Kino.JS.Live
  use Kino.SmartCell, name: "Wren script"

  @impl true
  def init(_attrs, ctx) do
    {:ok, ctx, editor: [attribute: "source", language: "javascript"]}
  end

  @impl true
  def handle_connect(ctx) do
    {:ok, %{}, ctx}
  end

  @impl true
  def to_attrs(_ctx) do
    %{}
  end

  @impl true
  def to_source(attrs) do
    quote do
      path = Temp.path!()
      File.write!(path, unquote(attrs["source"]))

      System.shell(
        """
        trap "rm -f #{path}" 0 2 3 15
        #{Wren.path()} #{path}
        """,
        into: IO.stream(),
        stderr_to_stdout: true
      )
      |> elem(1)
    end
    |> Kino.SmartCell.quoted_to_string()
  end

  asset "main.js" do
    """
    export function init(ctx, payload) {
      ctx.importCSS("main.css");

      root.innerHTML = `
        <div class="app">
          Wren script
        </div>
      `;
    }
    """
  end

  asset "main.css" do
    """
    .app {
      padding: 8px 16px;
      border: solid 1px #cad5e0;
      border-radius: 0.5rem 0.5rem 0 0;
      border-bottom: none;
    }
    """
  end
end

Kino.SmartCell.register(KinoGuide.WrenCell)
<!-- livebook:{"attrs":{"source":"System.print(\"Hello, world!\")\n\nclass Wren {\n  flyTo(city) {\n    System.print(\"Flying to %(city)\")\n  }\n}\n\nvar adjectives = Fiber.new {\n  [\"small\", \"clean\", \"fast\"].each {|word| Fiber.yield(word) }\n}\n\nwhile (!adjectives.isDone) System.print(adjectives.call())"},"kind":"Elixir.KinoGuide.WrenCell","livebook_object":"smart_cell"} -->
<!-- livebook:{"attrs":{"source":"for (yPixel in 0...24) {\n  var y = yPixel / 12 - 1\n  for (xPixel in 0...80) {\n    var x = xPixel / 30 - 2\n    var x0 = x\n    var y0 = y\n    var iter = 0\n    while (iter < 11 && x0 * x0 + y0 * y0 <= 4) {\n      var x1 = (x0 * x0) - (y0 * y0) + x\n      var y1 = 2 * x0 * y0 + y\n      x0 = x1\n      y0 = y1\n      iter = iter + 1\n    }\n    System.write(\" .-:;+=xX$& \"[iter])\n  }\n  System.print(\"\")\n}"},"kind":"Elixir.KinoGuide.WrenCell","livebook_object":"smart_cell"} -->

#{Wren.path()} #{path}

#{Wren.path()} #{path}で、wrenというプログラミング言語を実行しています。
path変数には、Temp.path/1で取得したテンポラリファイルのパスが入ります。
#{Wren.path()}には実行環境にあわせたwrenの実行バイナリが入っています。

wren <file_path>
ということです。

Elixirに例えると、elixir sample.exsみたいなものです。

trap "rm -f #{path}" 0 2 3 15

#{Wren.path()} #{path}の前にこれが書いてあります。
ファイルを消してそうだけど、実行する前に消しちゃうの?、0 2 3 15って何? となりました。

trap 0 2 3 15でググって最初にでたページです。

詳しくはこちらに譲るとして、要はwrenというプログラミング言語を実行したあとに、テンポラリファイルを消すということをやっています。
お行儀良いです。
心配りが行き届いています。
Niceです! Camiloさん!!!

おわりに

ElixirCL/wren-livebookを動かすことを楽しみました。
wrenというプログラミング言語を私ははじめて知りました。
Smart cellを独自に定義できることを知りました。

Camiloさん、ありがとうございます!

17
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?