Category: ‘Elixir’

Phoenix で CKEDITOR is not definedエラー

2017年7月4日 Posted by PURGE

環境

Elixir: 1.4.4
Phoenix: 1.2.2

とあるBootstrap のデザインテンプレートを利用しようとしたが、付属のJSとの相性が良くない。
最低限のJSをデプロイしていたが、下記のJavascriptエラーにハマる。

Uncaught ReferenceError: CKEDITOR is not defined

結論から言うと、Phoenixが使用している Brunch というJSのパッケージ管理が邪魔しているようだった。

特にJSのパッケージ管理に困っているわけでなく、むしろ最近のJS界隈の用語には付いて行けてないので、利用するJSは、直接手書きしても問題ない。

config/dev.exs

config :phoenix_sample, PhoenixSample.Endpoint,
  http: [port: 4000],
  debug_errors: true,
  code_reloader: true,
  check_origin: false
  # コメントアウト
  # watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
  #                   cd: Path.expand("../", __DIR__)]]


※但し、CSSもBrunch等で、一つのCSSにまとめている場合は、CSSとFONTのパスの問題を引き起こす可能性があるので注意。

priv/static/js に必要なJSファイルのみ配置する。 app.js / app.js.map への参照は削除

おそらくこれで、不要なJSを参照しなくなるので、Javascriptエラーは無くせるので、問題ないはず。

Brunchとか、JSのパッケージ管理の勉強は、困ったときにゆくゆくに。

Phoenix プロジェクト作成

2017年7月4日 Posted by PURGE

// プロジェクト作成
$ mix phoenix.new PhoenixSample --database mysql --app phoenix_sample
// サーバ起動
$ cd PhoenixSample
$ mix phoenix.server

必要最低限の初期テンプレート

<!DOCTYPE html>
<html lang="ja">
  <head>
    <link rel="stylesheet" href="<%= static_path(@conn, "/css/app.css") %>">
  </head>
  <body>
      <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
      <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
        <%= render @view_module, @view_template, assigns %>
    <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
  </body>
</html>

Elixir Fileの読み込み

2017年6月29日 Posted by PURGE

{:ok, file} = File.read("sample.csv")
File.close file

file |> Stream.map(&( String.trim(&1)))

IO.puts file

Ruby と Python と Elixir と。

2016年12月30日 Posted by PURGE

除算の違い。

# Ruby
puts 3.to_f / 2 #=> 1.5
puts 3 / 2      #=> 1

# Python
print(3 / 2) # => 1.5
print(3 // 2) # => 1

# Elixir ※1.4以降
require Integer
IO.puts(3 / 2) # => 1.5
IO.puts(Integer.floor_div(3, 2)) # => 1

剰余の違い。

# Ruby
puts 5 % 2 #=> 1

# Python
print(5 % 2) # => 1

# Elixir ※1.4以降
require Integer
IO.puts(Integer.mod(5, 1)) # => 1

べき乗の違い

# Ruby
puts 2 ** 3 #=> 8

# Python
print(2 ** 3) # => 8

# Elixir ※Erlangの関数使用
IO.puts(:math.pow(2,3)|> round) # => 8

Elixir の with について

2016年9月14日 Posted by PURGE

公開されている情報が、なかなか理解できないので手を動かしてみた。

name = "Pochi"
IO.puts "Hello #{name} "  #=> "Hello Pochi"

with name = "Tama",
  do: IO.puts "Hello #{name} "  #=> "Hello Tama"

IO.puts "Hello #{name} "  #=> "Hello Pochi"

簡単に言うと、with ブロック内のスコープが存在するということ。
なるほど。

ElixirのHeadとTailについて

2016年7月16日 Posted by PURGE

[head | tail]の挙動が、いまひとつわからなかった。
しかし、どうもErlang や Elixir の構文では、この概念が重要な気がしたので、ちょっと理解をしようと思う。

リストを作成して、[head | tail]で受けると、リストの先頭と、それ以降が分割される。

iex(1)> list = [1,2,3,4,5]
[1, 2, 3, 4, 5]
iex(2)> [head | tail] = list
[1, 2, 3, 4, 5]
iex(3)> head
1
iex(4)> tail
[2, 3, 4, 5]

ちなみに、リストを分割する関数も存在する。

iex(5)> hd(list)
1
iex(6)> tl(list)
[2, 3, 4, 5]

この概念は、再帰処理とかで基本になるので、ここで整理しておく。

Elixir ファイル読み込み

2016年7月15日 Posted by PURGE

File読込み。

defmodule FileIO do
    def main do
        {:ok, file} = File.open("sample.txt", [:read, :utf8])
        Enum.each(IO.stream(file, :line), fn(line) ->
            IO.puts line
        end )
        File.close(file)
    end
end

Elixir プログラムの実行方法

2016年7月14日 Posted by PURGE

下記のモジュールファイルを作成する。

MyModule.exs

defmodule MyModule do
  def hello() do
    IO.puts "Hello"
  end
end

これを実行するには、下記コマンドにてコンパイルする。

$ elixirc MyModule.exs 

または、コンソールにてコンパイル。

$ iex
Erlang/OTP 18 [erts-7.3]  [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

Interactive Elixir (1.3.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> c("MyModule.exs")
[MyModule]

そのまま実行するには、

$ elixir -e MyModule.hello
Hello

iexから実行するには、

$ iex MyModule.exs 
Erlang/OTP 18 [erts-7.3]  [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

warning: redefining module MyModule (current version loaded from Elixir.MyModule.beam)
  MyModule.exs:1

Interactive Elixir (1.3.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> MyModule.hello
Hello
:ok

Elixir関数定義

2016年7月14日 Posted by PURGE

以下は、同じらしい。

    fun = &(&1 + 5)
    fun.(2)
    fun2 = fn(a) -> a + 5 end
    fun2.(2)

関数型言語の慣れが必要です。

Elixir エラーハンドリングのパターン

2016年7月14日 Posted by PURGE

存在しないファイルを読み込んだ時、:ok は帰ってこない為、パターンマッチに失敗してエラーとなる。

iex(1)> {:ok, file} = File.read "non_exist_file.txt"
** (MatchError) no match of right hand side value: {:error, :enoent}

存在しないファイルを読み込んだ時、:error が帰ってくる為、パターンマッチに失敗しない。

iex(2)> {:error, enoent} = File.read "non_exist_file.txt"
{:error, :enoent}

普通の言語なら、下記の2つの文をif文で制御するところだが、上記の制御を振り分けるためには、case文を使用するようだ。

case File.read "non_exist_file.txt" do
    {:ok, file} -> IO.puts "OK!!"
    {:error, enoent} -> IO.puts "File not found Error!!"
end

中々、慣れない。