Phân biệt các từ khóa use, alias, require và import
elixir
37
White

Toàn Hà viết ngày 10/07/2018

Khi mới tiếp cận với Elixir các bạn có thể sẽ phân vân điểm khác nhau giữa các từ khoá trên. Bài viết này so sánh các từ khoá đó thông qua cách sử dụng

1. import

Hiểu đơn giản nó sẽ bê toàn bộ functions và macros của module B vô module A để sử dụng. Mình có thể gọi tắt 1 function trong B mà không cần bắt đầu bằng tên module.

defmodule A do
  def say_world() do
    IO.puts("world")
  end

  defmacro if_unless(expr, opts) do
    quote do
      if !unquote(expr), unquote(opts)
    end
  end
end

defmodule B do
  import A

  def say_hello do
    IO.puts("Hello ")
    if_unless false do
      say_world()
    end
  end
end

Có thể sử dụng thêm 2 từ khóa only nếu chỉ muốn lấy 1 số hàm, marco hoặc từ khóa except nếu muốn loại từ hàm hay macro nào đó

import List, only: [flatten: 1]
import String, except: [split: 2]

Import có thể sử dụng bên trong function và có scope chỉ ở trong function đó.

defmodule Math do
    def some_function do
        # 1) Disable "if/2" from Kernel
        import Kernel, except: [if: 2]

        # 2) Require the new "if/2" macro from MyMacros
        import MyMacros

        # 3) Use the new macro
        if do_something, it_works
    end
end

Lưu ý: Các hàm bắt đầu bằng _ sẽ không được import. Ví dụ: (__build__, ...)

2. require

Khi muốn sử dụng marco của 1 module nào đó, bắt buộc phải require module đó trước khi gọi marco

defmodule A do
  def say_world() do
    IO.puts("world")
  end

  defmacro if_unless(expr, opts) do
    quote do
      if !unquote(expr), unquote(opts)
    end
  end
end

defmodule B do
  require A

  def say_hello do
    IO.puts("Hello ")

    A.if_unless false do
      A.say_world()
    end
  end
end

3. alias

Dùng để setup 1 alias name cho 1 module. Mặc định thì alias sẽ lấy phần cuối cùng trong tên module làm tên alias.

defmodule A do
    alias Foo.Bar.Baz

    def funcA do
        Baz.some_func()
    end
end

Có thể sử dụng key as để định nghĩa 1 tên khác.

defmodule A do
    alias Foo.Bar.Baz, as: FBar

    def funcA do
        FBar.some_func()
    end
end

Mình có thể định nghĩa nhiều alias có module tương tự nhau trong cùng 1 hàng

alias Foo.Bar
alias Foo.Baz
alias Foo.Biz

> alias Foo.{Bar, Baz, Biz}

Chú ý: import/2, require/2alias/2 có thế định nghĩa trong từng function khác nhau không nhất thiết phải để ngay sau defmodule và nó không ảnh hưởng scope lẫn nhau.

4. use

Thường xài kiểu như abstract, Khi module B use module A, nó sẽ invoke marco __using__ trong module A

defmodule A do
  defmacro __using__(opts) do
    quote do
      IO.puts("Hello ")
    end
  end
end

defmodule B do
  use A, key1: "abc"

  def say_hello do
    IO.puts("World")
  end
end

đoạn code trên tương đương với

defmodule B do
  B.__using__([key1: "abc"])

  def say_hello do
    IO.puts("World")
  end
end

use thường được dùng khi muốn định nghĩa 1 behavior cho 1 module. Ví dụ trong Phoenix Framework. Controller được định nghĩa

defmodule ApiWeb do
...
    def controller do
        quote do
            use Phoenix.Controller, namespace: ApiWeb
            import Plug.Conn
            import ApiWeb.Router.Helpers
            import ApiWeb.Gettext
            require Logger
        end
    end
...
end

defmodule ApiWeb.PageController do
    use ApiWeb, :controller
    ...
end

Lưu ý: Không nên định nghĩa hàm ở trong __using__/1

Kết

Các bạn có thể tham gia vào channel #elixircộng đồng Ruby Việt Nam để thảo luận thêm về các vấn đề khi lập trình với elixir :)

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Toàn Hà

2 bài viết.
10 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
13 2
Mục đích bài viết này để 1. Giới thiệu về phương pháp lập trình bất đồng bộ với cách tiếp cận khác những ngôn ngữ như Java hoặc C. 2. Những bước đầ...
Toàn Hà viết hơn 1 năm trước
13 2
Bài viết liên quan
White
9 6
Chưa xem phần 2? Xem (Link) Trong bài viết này tôi giới thiệu cho các bạn về khái niệm function arity, một cách gọi mĩ miều của số lượng argument ...
Lơi Rệ viết gần 4 năm trước
9 6
White
6 1
Bạn đang viết application với Elixir? Bạn sắp release sản phẩm hay đơn giản thỉnh thoảng bạn không biết tại sao service A lại lăn đùng ra chết hay ...
Trần Việt Thắng viết 10 tháng trước
6 1
White
1 0
Custom Ecto.Type Version hiện tại của Ecto.Type không support một số datatype sử dụng khi validate. Ví dụ như MapSet. Thành ra đành phải tự viết đ...
Vie viết 2 năm trước
1 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
2 bài viết.
10 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!