From 4106fd1704903e65b02ca156a044d8749b96a4b8 Mon Sep 17 00:00:00 2001 From: niku Date: Thu, 27 Mar 2014 19:51:08 +0900 Subject: [PATCH 01/15] Translate into japanese(1 Interactive Elixir) --- getting_started/1.markdown | 66 ++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/getting_started/1.markdown b/getting_started/1.markdown index 8b8af84d6..d622d6601 100644 --- a/getting_started/1.markdown +++ b/getting_started/1.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 1 Interactive Elixir +title: 1 Elixirをインタラクティブに動かす - Interactive Elixir guide: 1 --- @@ -8,34 +8,72 @@ guide: 1
+ようこそ! + Welcome! +Elixirをどうやって始めたらよいかをこのチュートリアルでお伝えしようと思います.この章ではインストールとIExと呼ばれているElixirのインタラクティブシェルの使いかたについて説明します. + In this tutorial we are going to show you how to get started with Elixir. This chapter will cover installation and how to get started with the Interactive Elixir shell called IEx. +もしこのサイトで何かおかしなところを見つけたら,[ぜひバグレポートを書いたりプルリクエストを送ってください](https://github.com/elixir-lang/elixir-lang.github.com).もし言語のバグのようだとお考えなら[言語の課題管理システムへお知らせください](https://github.com/elixir-lang/elixir/issues). + If you find any errors in the tutorial or on the website, [please report a bug or send a pull request to our issue tracker](https://github.com/elixir-lang/elixir-lang.github.com). If you suspect it is a language bug, [please let us know in the language issue tracker](https://github.com/elixir-lang/elixir/issues). +それでは始めましょう! + Let's get started! -## 1.1 Installing Erlang +## 1.1 Erlangのインストール - Installing Erlang + +Elixirを動かすために唯一必要なのはErlang(バージョン17.0かそれ以降)で,[コンパイル済パッケージ](https://www.erlang-solutions.com/downloads/download-erlang-otp)を使うと簡単にインストールできます.もしソースコードから直接インストールしたい場合,[Erlangのサイト](http://www.erlang.org/download.html)をみるとわかりますし,[Riakのドキュメント](http://docs.basho.com/riak/1.3.0/tutorials/installation/Installing-Erlang/)にも素晴しいチュートリアルがあります. The only prerequisite for Elixir is Erlang, version 17.0 or later, which can be easily installed with [Precompiled packages](https://www.erlang-solutions.com/downloads/download-erlang-otp). In case you want to install it directly from source, it can be found on [the Erlang website](http://www.erlang.org/download.html) or by following the excellent tutorial available in the [Riak documentation](http://docs.basho.com/riak/1.3.0/tutorials/installation/Installing-Erlang/). +Windowsの開発者の方にはコンパイル済パッケージをお勧めしています.UNIXプラットフォームの場合は様々なパッケージ管理ツールからErlangをインストールできると思いますので普段お使いのものをご利用ください. + For Windows developers, we recommend the precompiled packages. Those on a UNIX platform can probably get Erlang installed via one of the many package management tools. +> 注: 様々なパッケージ管理ツールでErlangを提供していますが,Elixirを利用するにはつい最近リリースされたErlang 17が必要です.Erlangをインストールする際にご注意ください. + > Note: Although many package management tools provide Erlang, Elixir requires Erlang 17 which has been released just recently. So have that in mind before picking your Erlang installation. +Erlangをインストールした後,コマンドライン(コマンドプロンプト)を開いて`erl`と打ち,Erlangのバージョンを調べましょう.次のような情報を見られると思います: + After Erlang is installed, you should be able to open up the command line (or command prompt) and check the Erlang version by typing `erl`. You will see some information as follows: Erlang/OTP 17 (erts-6) [64-bit] [smp:2:2] [async-threads:0] [hipe] [kernel-poll:false] +Erlangをどうやってインストールしたかによりますが,ErlangのバイナリへPATHが通っていないかもしれません.必ず[PATH](http://en.wikipedia.org/wiki/Environment_variable)へErlangのバイナリを含めておいてください,そうしないとElixirが動きません! + Notice that depending on how you installed Erlang, Erlang binaries won't be available in your PATH. Be sure to have Erlang binaries in your [PATH](http://en.wikipedia.org/wiki/Environment_variable), otherwise Elixir won't work! +Erlangが起動し動作したなら,Elixirをインストールしましょう.ディストリビューションによりコンパイル済パッケージから入手したり,ソースからコンパイルしたりできます. + After Erlang is up and running, it is time to install Elixir. You can do that via Distributions, Precompiled package or Compiling from Source. -## 1.2 Distributions +## 1.2 ディストリビューション - Distributions + +このチュートリアルではElixir v0.13かそれ以降が必要で,いくつかのディストリビューションでは既に用意されています: This tutorial requires Elixir v0.14 or later and it may be available in some distributions: +* Mac OS XのHomebrew + * `brew update`と打ちhomebrewを最新版へアップデートします + * `brew install elixir`でElixirをインストールします +* Fedora 17+ や Fedora Rawhide + * `sudo yum -y install elixir` +* Arch Linux (on AUR) + * `yaourt -S elixir` +* openSUSE (and SLES 11 SP3+) + * `zypper ar -f obs://devel:languages:erlang/ erlang`でErlang開発リポジトリを追加します + * `zypper in elixir`でElixirをインストールします +* Gentoo + * `emerge --ask dev-lang/elixir` +* WindowsのChocolatey + * `cinst elixir` + + * Homebrew for Mac OS X * Update your homebrew to latest with `brew update` * Install Elixir: `brew install elixir` @@ -51,30 +89,44 @@ This tutorial requires Elixir v0.14 or later and it may be available in some dis * Chocolatey for Windows * `cinst elixir` +もし上記のどのディストリビューションをお使いでなくてもご心配なく.コンパイル済パッケージも用意してあります! + If you don't use any of the distributions above, don't worry, we also provide a precompiled package! -## 1.3 Precompiled package +## 1.3 コンパイル済パッケージ - Precompiled package + +Elixirは[リリース毎にコンパイル済パッケージ](https://github.com/elixir-lang/elixir/releases/)を提供しています.パッケージをダウンロードして解凍すると`bin`ディレクトリの中にある`elixir`や`iex`がすぐに実行できます.簡単に開発をするために,環境変数PATHへElixirの`bin`へのパスを追加しておくことをお勧めします. Elixir provides a [precompiled package for every release](https://github.com/elixir-lang/elixir/releases/). After downloading and unzip-ing the package, you are ready to run the `elixir` and `iex` commands from the `bin` directory. It is recommended that you also add Elixir's `bin` path to your PATH environment variable to ease development. -## 1.4 Compiling from source (Unix and MinGW) +## 1.4 ソースからコンパイルする(UnixやMinGWの場合) - Compiling from source (Unix and MinGW) + +ちょっとした手順でElixirをダウンロードしてコンパイルすることができます.[最終安定版をここ](https://github.com/elixir-lang/elixir/releases/)から手にいれて解凍し,解凍したディレクトリの中で`make`を実行します.すると`bin`ディレクトリの中にある`elixir`や`iex`がすぐに実行できます.簡単に開発をするために,環境変数PATHへElixirの`bin`へのパスを追加しておくことをお勧めします: You can download and compile Elixir in few steps. You can get the [latest stable release here](https://github.com/elixir-lang/elixir/releases/), unpack it and then run `make` inside the unpacked directory. After that, you are ready to run the `elixir` and `iex` commands from the `bin` directory. It is recommended that you add Elixir's `bin` path to your PATH environment variable to ease development: $ export PATH="$PATH:/path/to/elixir/bin" +もうちょっと刺激が欲しければ,masterからコンパイルすることもできます: + In case you are feeling a bit more adventurous, you can also compile from master: $ git clone https://github.com/elixir-lang/elixir.git $ cd elixir $ make clean test +テストが通れば使えます.もしそうならなければ気軽に[Githubにある課題管理](https://github.com/elixir-lang/elixir)へ課題を登録してください. + If the tests pass, you are ready to go. Otherwise, feel free to open an issue [in the issues tracker on Github](https://github.com/elixir-lang/elixir). -## 1.5 Interactive mode +## 1.5 インタラクティブモード - Interactive mode + +エリクサーをインストールすると`iex`,`elixir`そして`elixirc`の3つのコマンドが実行できるようになります.ソースからコンパイルしたか,コンパイル済パッケージをお使いの場合,3つのコマンドは`bin`ディレクトリの中にあります. When you install Elixir, you will have three new executables: `iex`, `elixir` and `elixirc`. If you compiled Elixir from source or are using a packaged version, you can find these inside the `bin` directory. +それでは,"Interactive Elixir"略して`iex`を起動してみましょう.インタラクティブモードではElixirの式を入力でき,すぐに結果を見ることができます.試しにいくつか式を入力してみましょう: + For now, let's start by running `iex` which stands for Interactive Elixir. In interactive mode, we can type any Elixir expression and get its result straight away. Let's warm up with some basic expressions: ```text @@ -86,4 +138,6 @@ iex> "hello" <> " world" "hello world" ``` +もう何でもできそうですね!次の章では言語構造や基本的な型に慣れるためにインタラクティブシェルを沢山使います.次の章に進みましょう. + It seems we are ready to go! We will use the interactive shell quite a lot in the next chapters to get a bit more familiar with the language constructs and basic types, starting in the next chapter. From 9219248de79ea0204b58c7d8c9163780d33272d0 Mon Sep 17 00:00:00 2001 From: niku Date: Fri, 28 Mar 2014 10:43:17 +0900 Subject: [PATCH 02/15] Translate into japanese(2 Basic types) --- getting_started/2.markdown | 120 ++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 9 deletions(-) diff --git a/getting_started/2.markdown b/getting_started/2.markdown index a3bb846e3..3e96a18e8 100644 --- a/getting_started/2.markdown +++ b/getting_started/2.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 2 Basic types +title: 2 基本的な型 - Basic types guide: 2 --- @@ -8,6 +8,8 @@ guide: 2
+この章ではElixirの基本的な型: integers, floats, atoms, lists と strings について学びます.いくつかの基本的な型は: + In this chapter we will learn more about Elixir basic types: integers, floats, atoms, lists and strings. Some basic types are: ```iex @@ -20,7 +22,9 @@ iex> [1, 2, 3] # list iex> {1, 2, 3} # tuple ``` -## 2.1 Basic arithmetic +## 2.1 基本的な数値 - Basic arithmetic + +`iex`を開いて以下の式を入力しましょう: Open up `iex` and type the following expressions: @@ -33,6 +37,8 @@ iex> 10 / 2 5.0 ``` +`10 / 2`が整数`5`ではなく浮動小数点`5.0`を返すことに注意してください.これは期待通りの動作です.エリクサーでは`/`演算子は常に浮動小数点を返します.もし整数の商や余りが必要なら関数`div`や`rem`を呼べばできます: + Notice that `10 / 2` returned a float `5.0` instead of an integer `5`. This is expected. In Elixir, the operator `/` always returns a float. If you want to do integer division or get the division remainder, you can invoke the `div` and `rem` functions: ```iex @@ -44,8 +50,12 @@ iex> rem 10, 3 1 ``` +関数を呼び出すのに括弧は必須ではないことに注意してください. + Notice that parentheses are not required in order to invoke a function. +Elixirは2進数,8進数,16進数の入力もできます: + Elixir also supports shortcut notations for entering binary, octal and hexadecimal numbers: ```iex @@ -57,6 +67,8 @@ iex> 0x1F 31 ``` +浮動小数点は1つ以上の数字のあとに点が必要で,指数として`e`を使うこともできます: + Float numbers require a dot followed by at least one digit and also support `e` for the exponent number: ```iex @@ -66,9 +78,13 @@ iex> 1.0e-10 1.0e-10 ``` +Elixirの浮動小数点は64ビットの倍精度です. + Floats in Elixir are 64 bit double precision. -## 2.2 Booleans +## 2.2 真理値 - Booleans + +Elixirでは真理値として`true`と`false`を使えます. Elixir supports `true` and `false` as booleans. @@ -79,8 +95,12 @@ iex> true == false false ``` +Elixirは変数の型を調べて真理値を返す関数群を提供しています.例えば,関数`is_boolean/1`では変数がbooleanかどうか調べることができます: + Elixir provides a bunch of predicate functions to check for a value type. For example, the `is_boolean/1` function can be used to check if a value is a boolean or not: +> 注: Elixirの中の関数は名前と引数の数(つまり項数)で表されます.つまり`is_boolean/1`は`is_boolean`という名前で引数を1つ取る特定の関数を示します.`is_boolean/2`は同じ名前ですが項数が異なるため,別の(存在しない)関数を表します. + > Note: Functions in Elixir are identified by name and by number of arguments (i.e. arity). Therefore, `is_boolean/1` identifies a function named `is_boolean` that takes 1 argument. `is_boolean/2` identifies a different (nonexistent) function with the same name but different arity. ```iex @@ -90,11 +110,17 @@ iex> is_boolean(1) false ``` +もし引数が整数,浮動小数点あるいはそのどちらかであることを調べたいなら,それぞれ`is_integer/1`,`is_float/1`か`is_number/1`を使うことができます. + You can also use `is_integer/1`, `is_float/1` or `is_number/1` to check, respectively, if an argument is an integer, a float or either. +> メモ: シェルの中で`h`を押すといつでもシェルの使い方を表示できます.`h`は全ての関数のドキュメントへアクセスするのにも使えます.例えば`h is_integer/1`と打つと関数`is_integer/1`のドキュメントが表示できます.演算子や他の構成物でも同じように使えます.`h ==/2`を試してみてください. + > Note: at any moment you can type `h` in the shell to print information on how to use the shell. The `h` helper can also be used to access documentation for any function. For example, typing `h is_integer/1` is going to print the documentation for the `is_integer/1` function. It also works with operators and other constructs (try `h ==/2`). -## 2.3 Atoms +## 2.3 アトム - Atoms + +アトムは名前が自身の値を表わしている定数です.別のいくつかの言語ではこれをシンボルと呼んでいます. Atoms are constants where their name is their own value. Some other languages call these symbols. @@ -105,6 +131,8 @@ iex> :hello == :world false ``` +真理値`true`と`false`は実はアトムです: + The booleans `true` and `false` are, in fact, atoms: ```iex @@ -114,7 +142,9 @@ iex> is_atom(false) true ``` -## 2.4 Strings +## 2.4 文字列 - Strings + +Elixirの文字列は二重引用符の中に書き,UTF-8でエンコードされます: Strings in Elixir are inserted in between double quotes, and they are encoded in UTF-8: @@ -123,6 +153,8 @@ iex> "hellö" "hellö" ``` +Elixirでは文字補完も使えます: + Elixir also supports string interpolation: ```iex @@ -130,6 +162,8 @@ iex> "hellö #{:world}" "hellö world" ``` +文字列はエスケープシーケンスを使って改行コードを保持することもできます: + Strings can have line breaks in them or introduce them using escape sequences: ```iex @@ -140,6 +174,8 @@ iex> "hello\nworld" "hello\nworld" ``` +`IO`モジュールの関数`IO.puts/1`を使うことで文字列を表示することができます: + You can print a string using the `IO.puts/1` function from the `IO` module: ```iex @@ -149,8 +185,12 @@ world :ok ``` +関数`IO.puts/1`が表示のあとにアトム`:ok`を返していることに注意してください. + Notice the `IO.puts/1` function returns the atom `:ok` as result after printing. +文字列はElixir内部ではバイト列(バイナリ)で表現されています: + Strings in Elixir are represented internally by binaries which are sequences of bytes: ```iex @@ -158,6 +198,8 @@ iex> is_binary("hellö") true ``` +文字列のバイト数を得ることもできます: + We can also get the number of bytes in a string: ```iex @@ -165,6 +207,8 @@ iex> byte_size("hellö") 6 ``` +この文字列は5文字であるにもかわらず,バイト数は6であることに注意してください.これは文字"ö"がUTF-8では2バイトを占めるためです.正確な文字の長さを取得するには関数`String.length/1`を使えます: + Notice the number of bytes in that string is 6, even though it has 5 characters. That's because the character "ö" takes 2 bytes to be represented in UTF-8. We can get the actual length of the string, based on the number of characters, by using the `String.length/1` function: ```iex @@ -172,6 +216,8 @@ iex> String.length("hellö") 5 ``` +[Stringモジュール](/docs/stable/elixir/String.html)はユニコード標準で定義された文字を操作する関数たちを含んでいます: + The [String module](/docs/stable/elixir/String.html) contains a bunch of functions that operate on strings as defined in the Unicode standard: ```iex @@ -179,6 +225,8 @@ iex> String.upcase("hellö") "HELLÖ" ``` +Elxirでは`単一引用符でくくられた`文字列と`二重引用符でくくられた`文字列が同じではなく,異なる型で表現されることに気をつけてください: + Keep in mind `single-quoted` and `double-quoted` strings are not equivalent in Elixir as they are represented by different types: ```iex @@ -186,9 +234,13 @@ iex> 'hellö' == "hellö" false ``` +ユニコードのサポートや単一引用符と二重引用符でくくられた文字列の違いについては"バイナリ,文字列と文字のリスト"の章でもっと詳しくやります. + We will talk more about Unicode support and the difference between single and double-quoted strings in the "Binaries, strings and char lists" chapter. -## 2.5 Anonymous functions +## 2.5 匿名関数 - Anonymous functions + +関数はキーワード`fn`と`end`で区切られます: Functions are delimited by the keywords `fn` and `end`: @@ -205,10 +257,16 @@ iex> add.(1, 2) 3 ``` +Elixirでは関数は"第一級市民"です.つまり,整数や文字列と同じように他の関数の引数へ渡せます.例えば,関数`add`を引数として`is_function/1`へ渡すと確かに`true`が返ってきます.`is_function/2`では関数の項数もチェックすることができます. + Functions are "first class citizens" in Elixir meaning they can be passed as arguments to other functions just as integers and strings can. In the example, we have passed the function in the variable `add` to the `is_function/1` function which correctly returned `true`. We can also check the arity of the function by calling `is_function/2`. +匿名関数を実行するには変数と括弧のあいだに点(`.`)が必要であることにも注目してください. + Note a dot (`.`) in between the variable and parenthesis is required to invoke an anonymous function. +匿名関数はクロージャです,つまり関数が定義されているスコープで保持している変数へアクセスすることができます: + Anonymous functions are closures, and as such they can access variables that are in scope when the function is defined: ```iex @@ -218,6 +276,8 @@ iex> add_two.(2) 4 ``` +関数の中で割り当てられた変数はその外側の環境に何の影響も及ぼさないことを覚えておいてください: + Keep in mind that a variable assigned inside a function does not affect its surrounding environment: ```iex @@ -229,7 +289,9 @@ iex> x 42 ``` -## 2.6 (Linked) Lists +## 2.6 (連結した)リスト - (Linked) Lists + +Elixirでは角括弧を値のリストを表すのに使います.値にはどんな型も入れられます: Elixir uses square brackets to specify a list of values. Values can be of any type: @@ -240,6 +302,8 @@ iex> length [1, 2, 3] 3 ``` +2つのリストは`++/2`や`--/2`演算子を使うことで繋げたり差し引いたりできます: + Two lists can be concatenated and subtracted using the `++/2` and `--/2` operators: ```iex @@ -249,6 +313,8 @@ iex> [1, true, 2, false, 3, true] -- [true, false] [1, 2, 3, true] ``` +チュートリアルの様々な場所でリストのheadとtailについて沢山話します.headはリストの最初の要素のことで,tailはリストの残りのことです.それらは`hd/1`と`tl/1`で取得することができます.リストを変数へ割り当てて,そのリストのheadとtailを取得してみましょう: + Throughout the tutorial, we will talk a lot about the head and tail of a list. The head is the first element of a list and the tail is the remainder of a list. They can be retrieved with the functions `hd/1` and `tl/1`. Let's assign a list to a variable and retrieve its head and tail: ```iex @@ -259,6 +325,8 @@ iex> tl(list) [2, 3] ``` +空リストからheadやtailを取得しようとするとエラーになります: + Getting the head or the tail of an empty list is an error: ```iex @@ -266,9 +334,13 @@ iex> hd [] ** (ArgumentError) argument error ``` +おおっと! + Oops! -## 2.7 Tuples +## 2.7 タプル - Tuples + +エリクサーはタプルを定義するのに中括弧を使います.リストのように,タプルは値を保持できます: Elixir uses curly brackets to define tuples. As lists, tuples can hold any value: @@ -279,6 +351,8 @@ iex> size {:ok, "hello"} 2 ``` +タプルは要素を連続したメモリ上に保存します.つまりインデックス毎に要素へアクセスしたり,タプルのサイズを入手するのはとても速いです(インデックスは0から始まります): + Tuples store elements contiguously in memory. This means accessing a tuple element per index or getting the tuple size is a fast operation (indexes start from zero): ```iex @@ -290,6 +364,8 @@ iex> tuple_size(tuple) 2 ``` +タプルと`set_elem/3`を使うと指定したインデックスへ要素をセットすることもできます: + It is also possible to set an element at a particular index in a tuple with `set_elem/3`: ```iex @@ -301,14 +377,22 @@ iex> tuple {:ok, "hello"} ``` +`set_elem/3`は新しいタプルを返すことに注意してください.Elixirのデータ型は変更不可能なため`tuple`という変数名で保持されているオリジナルのタプルは変更されません.変更不可であることにより,特定のコードがデータ構造を変更していないか気を配る必要はまったくなく,その分簡単になっています. + Notice that `set_elem/3` returned a new tuple. The original tuple stored in the `tuple` variable was not modified because Elixir data types are immutable. By being immutable, Elixir code is easier to reason about as you never need to worry if a particular code is mutating your data structure in place. +変更不可であることで,別のエンティティが同時に1つのデータ構造を変更しようと試みるといった,並行処理するコードでよく問題になるような競合状態のケースを考えなくてすみます. + By being immutable, Elixir also helps eliminate common cases where concurrent code has race conditions because two different entities are trying to change a data structure at the same time. -## 2.8 Lists or tuples? +## 2.8 リストにするかタプルにするか - Lists or tuples? + +リストとタプルはどう違うのでしょうか? What is the difference between lists and tuples? +リストは連結リストとしてメモリ上に記録されています.つまりリストの中のある要素はリストの次の要素の場所を示しており,次の要素はまた次の要素というように,リストの終わりがくるまで次の要素を取得していきます.こういったリストの中のそれぞれのペアのことを**コンスセル**と呼びます: + Lists are stored in memory as linked lists. This means each element in a list points to the next element, and then to the next element, until it reaches the end of a list. We call each of those pairs in a list a **cons cell**: ```iex @@ -316,6 +400,8 @@ iex> list = [1|[2|[3|[]]]] [1, 2, 3] ``` +つまりリストの長さにアクセスするのは直線的な操作だということです: サイズを知るにはリスト中の全ての要素を順番にたどっていかなくてはなりません.リストの手前に要素を追加する場合にのみリストを素早くアップデートできます: + This means accessing the length of a list is a linear operation: we need to traverse the whole list in order to figure out its size. Updating a list is fast as long as we are prepending elements: ```iex @@ -325,10 +411,16 @@ iex> list ++ [4] [1, 2, 3, 4] ``` +一番目の操作は,次の要素が`list`であるような新しいコンスを単に追加するだけなので速いです.二番目の操作はリスト全体を再構築して最後に新しい要素を追加しなくてはならないため遅いです. + The first operation is fast because we are simply adding a new cons that points to the remaining of `list`. The second one is slow because we need to rebuild the whole list and add a new element to the end. +一方,タプルは連続したメモリ上に記録されています.つまりタプルのサイズを知ったりインデックスを指定して要素にアクセスすることは速いです.しかし要素を更新したり追加するのはタプル全体をコピーしてから行う必要があるため大変です. + Tuples, on the other hand, are stored contiguously in memory. This means getting the tuple size or accessing an element by index is fast. However, updating or adding elements to tuples is expensive because it requires copying the whole tuple in memory. +これらの性能の特徴がデータ構造の使い方に影響します.タプルのごく一般的な使い方の一つとして関数からの返り値に情報を付与するということがあります.例えば関数`File.read/1`をみてみましょう: + Those performance characteristics dictate the usage of those data structures. One very common use case for tuples is to use them to return extra information from a function. For example, `File.read/1` is a function that can be used to read file contents and it returns tuples: ```iex @@ -338,8 +430,12 @@ iex> File.read("path/to/unknown/file") {:error, :enoent} ``` +もし`File.read/1`に与えられたパスが存在すれば,タプルの1番目の要素はアトム`:ok`となり,2番目の要素に内容が入って返ってきます.そうでなければ,タプルで`:error`とエラーの理由が返ります. + If the path given to `File.read/1` exists, it returns a tuple with the atom `:ok` as first element and the file contents as second. Otherwise, it returns a tuple with `:error` and the error reason. +だいたいの場合Elixirはあなたへ正しい方法をとらせようとします.例えばタプルの要素にアクセスする関数`elem/2`はありますが,同じような関数はリストには用意されていません: + Most of the time, Elixir is going to guide you to do the right thing. For example, there is a `elem/2` function to access a tuple item but there is no built-in equivalent for lists: ```iex @@ -349,8 +445,14 @@ iex> elem(tuple, 1) "hello" ``` +データ構造が持っている要素数を数える場合,Elixirは単純な規則: 操作が一定時間になる(つまり値があらかじめ計算されている)ものを関数名`size`と呼び,明示的に計算が必要なものは関数名`length`と呼ぶという規則に従います. + When "counting" the number of elements in a data structure, Elixir also abides by a simple rule: the function should be named `size` if the operation is in constant time (i.e. the value is pre-calculated) or `length` if the operation requires explicit counting. +例えば,今まで数を数える関数を4つ使ってきました:`byte_size/1`(文字列のバイト数),`tuple_size/1`(タプルのサイズ),`length/1`(リストの長さ)そして`String.length/1`(文字列の文字数).そこでも,`byte_size`は文字列のバイトサイズを求めるという軽い処理であったのに対し,ユニコード文字の数を調べる`String.length`は文字列全体への繰り返し処理が必要でした. + For example, we have used 4 counting functions so far: `byte_size/1` (for the number of bytes in a string), `tuple_size/1` (for the tuple size), `length/1` (for the list length) and `String.length/1` (for the number of characters in a string). That said, we use `byte_size` to get the number of bytes in a string, which is cheap, but retrieving the number of unicode characters uses `String.length`, since the whole string needs to be iterated. +Elixirにはデータ型として他にも`Port`,`Reference`や`PID`といったものがあります(よくプロセス間通信で使います),これらはプロセスについて話すときにさっと見ることにします.今は,型を操作する基本的ないくつかの演算子を見ていくことにしましょう. + Elixir also provides `Port`, `Reference` and `PID` as data types (usually used in process communication), and we will take a quick look at them when talking about processes. For now, let's take a look at some of the basic operators that go with our basic types. From a6849b53f668b7541faef9e198c4a09661592d25 Mon Sep 17 00:00:00 2001 From: niku Date: Mon, 31 Mar 2014 13:20:45 +0900 Subject: [PATCH 03/15] Translate into japanese(3 Basic operators) --- getting_started/3.markdown | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/getting_started/3.markdown b/getting_started/3.markdown index cb17c874b..144ac7b6a 100644 --- a/getting_started/3.markdown +++ b/getting_started/3.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 3 Basic operators +title: 3 基本的な演算子 - Basic operators guide: 3 --- @@ -8,8 +8,12 @@ guide: 3
+前の章で,Elixirで算術演算子として`+`,`-`,`*`,`/`を使えるのを見ました.整数の商と余りを求めるのに`div/2`と`rem/2`があることも知りました. + In the previous chapter, we saw Elixir provides `+`, `-`, `*`, `/` as arithmetic operators, plus the functions `div/2` and `rem/2` for integer division and remainder. +Elixirはリストを操作するのに`++`と`--`という演算子も提供しています: + Elixir also provides `++` and `--` to manipulate lists: ```iex @@ -19,6 +23,8 @@ iex> [1,2,3] -- [2] [1,3] ``` +文字列の結合は`<>`で行なえます: + String concatenation is done with `<>`: ```iex @@ -26,6 +32,8 @@ iex> "foo" <> "bar" "foobar" ``` +Elixirには3つの論理演算子`or`,`and`と`not`があります.これらの演算子は第一引数が真理値(`true`か`false`)であることを求めています: + Elixir also provides three boolean operators: `or`, `and` and `not`. These operators are strict in the sense that they expect a boolean (`true` or `false`) as their first argument: ```iex @@ -35,6 +43,8 @@ iex> false or is_atom(:example) true ``` +真理値でない場合は例外を発生させます: + Providing a non-boolean will raise an exception: ```iex @@ -42,6 +52,8 @@ iex> 1 and true ** (ArgumentError) argument error ``` +`or`と`and`は短絡演算子です.左側が条件を満たさなかった場合にのみ右側が実行されます: + `or` and `and` are short-circuit operators. They only execute the right side if the left side is not enough to determine the result: ```iex @@ -52,8 +64,12 @@ iex> true or error("This error will never be raised") true ``` +> メモ: Erlang開発者の方へ,Elixirの`and`と`or`は,Erlangの`andalso`と`orelse`とまったく同じです. + > Note: If you are an Erlang developer, `and` and `or` in Elixir actually map to the `andalso` and `orelse` operators in Erlang. +これらの論理演算子と違い`||`,`&&`と`!`はどんな型でも受けつけます.この場合`false`と`nil`以外はtrueとして評価されます: + Besides these boolean operators, Elixir also provides `||`, `&&` and `!` which accept arguments of any type. For these operators, all values except `false` and `nil` will evaluate to true: ```iex @@ -78,8 +94,12 @@ iex> !nil true ``` +まとめると,真理値を期待している場合は`and`,`or`と`not`を使います.真理値でない引数がきてよい場合は`&&`,`||`や`!`を使います. + As a rule of thumb, use `and`, `or` and `not` when you are expecting booleans. If any of the arguments are non-boolean, use `&&`, `||` and `!`. +Elixirは比較演算子として`==`,`!=`,`===`,`!==`,`<=`,`>=`,`<`と`>`を提供しています: + Elixir also provides `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` and `>` as comparison operators: ```iex @@ -91,6 +111,8 @@ iex> 1 < 2 true ``` +`==`と`===`の違いは後者の方が整数と浮動小数点数の比較に厳密である点です: + The difference between `==` and `===` is that the latter is more strict when comparing integers and floats: ```iex @@ -100,6 +122,8 @@ iex> 1 === 1.0 false ``` +Elixirでは異なる型を比較することもできます: + In Elixir, we can compare two different data types: ```iex @@ -107,10 +131,16 @@ iex> 1 < :atom true ``` +便利にするために異なる型を比較できるようになっています.こうすると並べ替えアルゴリズムで異なる型同士の順序付けについて心配する必要がありません.全体の並べ替え順序は以下のように定義されています: + The reason we can compare different data types is pragmatism. Sorting algorithms don't need to worry about different data types in order to sort. The overall sorting order is defined below: number < atom < reference < functions < port < pid < tuple < maps < list < bitstring +正確にこの順番を覚えておく必要はありませんが,こういった順番があることを知っておくことは大事です. + You don't actually need to memorize this ordering, but it is important just to know an order exists. +導入としてはこのくらいにしておきます.次の章では基本的な関数,型の変換やちょっとしたフロー制御について話しましょう. + Well, that is it for the introduction. In the next chapter, we are going to discuss some basic functions, data type conversions and a bit of control-flow. From f84c7531ad63450aaa90cbd9515d6c0c1150ca2c Mon Sep 17 00:00:00 2001 From: niku Date: Tue, 1 Apr 2014 14:27:29 +0900 Subject: [PATCH 04/15] Translate into japanese(4 Pattern matching) --- getting_started/4.markdown | 53 +++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/getting_started/4.markdown b/getting_started/4.markdown index c545cd215..1a048d55d 100644 --- a/getting_started/4.markdown +++ b/getting_started/4.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 4 Pattern matching +title: 4 パターンマッチング - Pattern matching guide: 4 --- @@ -8,9 +8,13 @@ guide: 4
+この章では,Elixirにおいて`=`演算子は実際にはマッチ演算子であり,データ構造へのパターンマッチをどのように使うかを見ていきます.最後に,既に束縛された値へアクセスする際に使用するピン演算子`^`について学びます. + In this chapter, we will show how the `=` operator in Elixir is actually a match operator and how to use it to pattern match inside data structures. Finally, we will learn about the pin operator `^` used to access previously bound values. -## 4.1 The match operator +## 4.1 マッチ演算子 - The match operator + +Elixirで変数へ割り当てるために`=`を何回か使ってきました. We have used the `=` operator a couple times to assign variables in Elixir. @@ -21,6 +25,8 @@ iex> x 1 ``` +Elixirにおいて`=`演算子は*マッチ演算子*と呼ばれています.なぜだか見てみましょう: + In Elixir, the `=` operator is actually called *the match operator*. Let's see why: ```iex @@ -30,8 +36,13 @@ iex> 2 = x ** (MatchError) no match of right hand side value: 1 ``` +`1 = x`が式として妥当であることに注意してください,そして左側も右側も両方同じ(1である)ためマッチします.両側がマッチしなかった場合,`MatchError`が発生します. + Notice that `1 = x` is a valid expression, and it matched because both the left and right side are equal to 1. When the sides do not match, a `MatchError` is raised. + +変数は`=`の左側にあるときにだけ割り当てられます: + A variable can only be assigned on the left side of `=`: ```iex @@ -39,9 +50,13 @@ iex> 1 = unknown ** (RuntimeError) undefined function: unknown/0 ```` +`unknown`という変数はまだ定義されていないため,Elixirはあなたが`unknown/0`という名前の関数を呼び出そうとしていると考えます,しかしそういった関数はありません. + Since there is no variable `unknown` previously defined, Elixir imagined you were trying to call a function named `unknown/0`, but there isn't such function. -## 4.2 Pattern matching +## 4.2 パターンマッチング - Pattern matching + +マッチ演算子は単純な値に対してのみ使えるわけではなく,複雑なデータ型を分解するのにも使えます.例えば,タプルにパターンマッチさせることができます: The match operator is not only used to match against simple values, but it is also useful for destructuring more complex data types. For example, we can pattern match on tuples: @@ -54,6 +69,8 @@ iex> b "world" ``` +パターンマッチは両側が対応していないとエラーになります.例えばタプルのサイズが異なる場合: + A pattern match will error in case the sides can't match. This is, for example, the case when the tuples have different sizes: ```iex @@ -61,6 +78,8 @@ iex> {a, b, c} = {:hello, "world"} ** (MatchError) no match of right hand side value: {:hello, "world"} ``` +そして異なる型を比較した場合: + And also when comparing different types: ```iex @@ -68,6 +87,8 @@ iex> {a, b, c} = [:hello, "world", "!"] ** (MatchError) no match of right hand side value: [:hello, "world", "!"] ``` +興味深いことに,特定の値へマッチさせることができます.以下の例では右側にあるタプルの最初の要素がアトム`:ok`から始まっている場合にのみ左側とマッチすることになります: + More interestingly, we can match on specific values. The example below asserts that the left side will only match the right side when the right side is a tuple that starts with the atom `:ok`: ```iex @@ -80,6 +101,8 @@ iex> {:ok, result} = {:error, :oops} ** (MatchError) no match of right hand side value: {:error, :oops} ``` +リストにもパターンマッチさせられます: + We can pattern match on lists: ```iex @@ -89,6 +112,8 @@ iex> a 1 ``` +リストではheadとtailというマッチングもできます: + A list also supports matching on its own head and tail: ```iex @@ -100,6 +125,8 @@ iex> tail [2, 3] ``` +関数`hd/1`と`tl/1`同じように,headとtailは空リストにマッチさせることができません: + Similar to the `hd/1` and `tl/1` functions, we can't match an empty list with a head and tail pattern: ```iex @@ -107,6 +134,8 @@ iex> [h|t] = [] ** (MatchError) no match of right hand side value: [] ``` +`[head | tail]`形式はパターンマッチングにだけ使えるのではなく,リストの先頭へ要素を追加するのにも使えます: + The `[head | tail]` format is not only used on pattern matching but also for prepending items to a list: ```iex @@ -116,9 +145,13 @@ iex> [0|list] [0, 1, 2, 3] ``` +パターンマッチングでタプルやリストなどのデータ構造を簡単に分解できるようになります.今後の章で見ていくように,これはElixirで再帰をする際の基本で,MapやBinaryなどの異なる型へうまく適用できます. + Pattern matching allows developers to easily destructure data types such as tuples and lists. As we will see in following chapters, it is one of the foundations of recursion in Elixir and applies to other types as well, like maps and binaries. -## 4.3 The pin operator +## 4.3 ピン演算子 - The pin operator + +Elixirの変数は再束縛できます: Variables in Elixir can be rebound: @@ -129,6 +162,8 @@ iex> x = 2 2 ``` +ピン演算子`^`は変数の再束縛ではなく以前にマッチした値とのマッチングをしたい場合に使われます: + The pin operator `^` can be used when there is no interest in rebinding a variable but rather in matching against its value prior to the match: ```iex @@ -142,6 +177,8 @@ iex> x 2 ``` +パターンの中で複数回使われているときは,全ての参照は同じパターンへ束縛されます: + Notice that if a variable is mentioned more than once in a pattern, all references should bind to the same pattern: ```iex @@ -151,6 +188,8 @@ iex> {x, x} = {1, 2} ** (MatchError) no match of right hand side value: {1, 2} ``` +パターンの値が何であるか気にしないことがあります.そのときは変数を`_`へ束縛するのが一般的です.例えばリストの先頭(head)にだけ何かする場合,tailをアンダースコアへ割り当てます: + In some cases, you don't care about a particular value in a pattern. It is a common practice to bind those values to the underscore, `_`. For example, if only the head of the list matters to us, we can assign the tail to underscore: ```iex @@ -160,6 +199,8 @@ iex> h 1 ``` +`_`はどこからも読むことができない特別な値です.読もうとすると未束縛のエラーになります: + The variable `_` is special in that it can never be read from. Trying to read from it gives an unbound variable error: ```iex @@ -167,6 +208,8 @@ iex> _ ** (CompileError) iex:1: unbound variable _ ``` +パターンマッチングで強力な構造を構築できますが,使いかたに制限があります.例えば,マッチの左側で関数を呼び出すことはできません.以下の例はうまくいきません: + Although pattern matching allows us to build powerful constructs, its usage is limited. For instance, you cannot make function calls on the left side of a match. The following example is invalid: ```iex @@ -174,4 +217,6 @@ iex> length([1,[2],3]) = 3 ** (ErlangError) erlang error :illegal_pattern ``` +パターンマッチの導入部分はおしまいです.次の章で見るように,パターンマッチングは言語を組み立てるのに良く出てきます. + This finishes our introduction to pattern matching. As we will see in the next chapter, pattern matching is very common in many language constructs. From 0dcc7713e7f6761982e2387e2b31779cb9c7076b Mon Sep 17 00:00:00 2001 From: niku Date: Wed, 2 Apr 2014 13:09:34 +0900 Subject: [PATCH 05/15] Translate into japanese(5 case, cond and if) --- getting_started/5.markdown | 102 +++++++++++++++++++++++++++++++++++-- 1 file changed, 97 insertions(+), 5 deletions(-) diff --git a/getting_started/5.markdown b/getting_started/5.markdown index 21ee02ae4..4684c3653 100644 --- a/getting_started/5.markdown +++ b/getting_started/5.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 5 case, cond and if +title: 5 case,condそしてif - case, cond and if guide: 5 --- @@ -8,9 +8,13 @@ guide: 5
+この章では`case`,`cond`そして`if`といった処理制御構造について学んでいきます. + In this chapter, we will learn about the `case`, `cond` and `if` control-flow structures. -## 5.1 case +## 5.1 case - case + +`case`によってある値がいずれか一つにマッチするまで複数のパターンと比較することができるようになります: `case` allows us to compare a value against many patterns until we find a matching one: @@ -25,6 +29,8 @@ iex> case {1, 2, 3} do ...> end ``` +もし既にある値とパターーンマッチさせたい場合,`^`を使わなければなりません: + If you want to pattern match against an existing variable, you need to use the `^` operator: ```iex @@ -36,6 +42,8 @@ iex> case 10 do ...> end ``` +句では,ガード(guard)を指定することで条件を拡張することができます: + Clauses also allow extra conditions to be specified via guards: ```iex @@ -47,8 +55,54 @@ iex> case {1, 2, 3} do ...> end ``` +最初の句は`x`が正の場合にのみマッチします.ErlangVMではガードで使える式に制限があります: + The first clause above will only match when `x` is positive. The Erlang VM only allows a limited set of expressions in guards: +* 比較演算子(`==`,`!=`,`===`,`!==`,`>`,`<`,`<=`,`>=`) +* 論理演算子(`and`,`or`)と否定演算子(`not`,`!`) +* 算術演算子(`+`,`-`,`*`,`/`) +* 左側がリテラルの場合の`<>`と`++` +* `in`演算子 +* 以下の全ての型チェック関数: + + * `is_atom/1` + * `is_binary/1` + * `is_bitstring/1` + * `is_boolean/1` + * `is_float/1` + * `is_function/1` + * `is_function/2` + * `is_integer/1` + * `is_list/1` + * `is_map/1` + * `is_number/1` + * `is_pid/1` + * `is_port/1` + * `is_reference/1` + * `is_tuple/1` + +* それに加えてこれらの関数: + + * `abs(number)` + * `bit_size(bitstring)` + * `byte_size(bitstring)` + * `div(integer, integer)` + * `elem(tuple, n)` + * `hd(list)` + * `length(list)` + * `map_size(map)` + * `node()` + * `node(pid | ref | port)` + * `rem(integer, integer)` + * `round(number)` + * `self()` + * `size(tuple | bitstring)` + * `tl(list)` + * `trunc(number)` + * `tuple_size(tuple)` + + * comparison operators (`==`, `!=`, `===`, `!==`, `>`, `<`, `<=`, `>=`) * boolean operators (`and`, `or`) and negation operators (`not`, `!`) * arithmetic operators (`+`, `-`, `*`, `/`) @@ -92,6 +146,8 @@ The first clause above will only match when `x` is positive. The Erlang VM only * `trunc(number)` * `tuple_size(tuple)` +ガードの中で起きたエラーは単純にガードの失敗とみなされてガードの外には影響しません: + Keep in mind errors in guards do not leak but simply make the guard fail: ```iex @@ -105,6 +161,8 @@ iex> case 1 do "Got 1" ``` +もしどの句にもマッチしなければ,エラーが発生します: + If none of the clauses match, an error is raised: ```iex @@ -114,6 +172,8 @@ iex> case :ok do ** (CaseClauseError) no case clause matching: :ok ``` +匿名関数でも句やガードを複数持つことができることに注意してください: + Note anonymous functions can also have multiple clauses and guards: ```elixir @@ -128,9 +188,13 @@ iex> f.(-1, 3) -3 ``` +匿名関数の句では引数の数が同じでなければなりません,そうでない場合はエラーになります. + The number of arguments in each anonymous function clause needs to be the same, otherwise an error is raised. -## 5.2 cond +## 5.2 cond - cond + +`case`は異なる値に対して(1つの値を)マッチさせようとするときにはうまく使えます.しかし場合によっては最初に評価した式がtrueになるまで複数の条件をチェックしたい場合があります.そのような場合に`cond`が使えるでしょう: `case` is useful when you need to match against different values. However, in many circumstances, we want to check different conditions and find the first one that evaluates to true. In such cases, one may use `cond`: @@ -146,8 +210,12 @@ iex> cond do "But this will" ``` +これは命令型言語の`else if`句と同じです(それらより使う機会は少ないですが). + This is equivalent to `else if` clauses in many imperative languages (although used way less frequently here). +もしtrueになる条件がなければ,エラーになります.そのため,最後の条件に`true`になるものを加えて,常にマッチさせることが必要になるかもしれません: + If none of the conditions return true, an error is raised. For this reason, it may be necessary to add a last condition equal to `true`, which will always match: ```iex @@ -161,6 +229,8 @@ iex> cond do ...> end ``` +最後に`cond`では`nil`と`false`以外はどんな値でもtrueとして扱うことに気をつけてください: + Finally, note `cond` considers any value besides `nil` and `false` to be true: ```iex @@ -171,7 +241,9 @@ iex> cond do "1 is considered as true" ``` -## 5.3 if and unless +## 5.3 ifとunless - if and unless + +`case`や`cond`とは違い,一つだけ条件をチェックしたい場合に便利な`if/2`や`unless/2`といったマクロも提供しています. Besides `case` and `cond`, Elixir also provides the macros `if/2` and `unless/2` which are useful when you need to check for just one condition: @@ -186,8 +258,12 @@ iex> unless true do nil ``` +もし`if/2`に渡した条件が`false`か`nil`で返ってきた場合,`do/end`で囲まれた部分は実行されず,単に`nil`が返ります.その逆になるのが`unless/2`です. + If the condition given to `if/2` returns `false` or `nil`, the body given between `do/end` is not executed and it simply returns `nil`. The opposite happens with `unless/2`. +これらでは`else`ブロックも使えます: + They also support `else` blocks: ```iex @@ -199,9 +275,13 @@ iex> if nil do "This will" ``` +> メモ: この言語で`if/2`や`unless/2`がマクロとして実装されているのがおもしろい点です;これらは他の様々な言語でそうであるように特別な言語構造です.[モジュール`Kernel`のドキュメント](/docs/stable/elixir/Kernel.html)で`if/2`のドキュメントやソースを調べることができます.モジュール`Kernel`には他にも演算子`+/2`や関数`is_function/2`といったような,あなたがコードを書くときにデフォルトで自動importされて使えるようになっているものが定義されています. + > Note: An interesting note regarding `if/2` and `unless/2` is that they are implemented as macros in the language; they are special language constructs as they would be in many languages. You can check the documentation and the source of `if/2` in [the `Kernel` module docs](/docs/stable/elixir/Kernel.html). The `Kernel` module is also where operators like `+/2` and functions like `is_function/2` are defined, all automatically imported and available in your code by default. -## 5.4 `do` blocks +## 5.4 `do`ブロック - `do` blocks + +ここまでで,私たちは4つの制御構造`case`,`cond`,`if`そして`unless`を学びました,そしてこれらは全て`do`/`end`ブロックで囲まれていました.実は`if`を以下のようにも書けます: At this point, we have learned four control structures: `case`, `cond`, `if` and `unless`, and they were all wrapped in `do`/`end` blocks. It happens we could also write `if` as follows: @@ -210,6 +290,8 @@ iex> if true, do: 1 + 2 3 ``` +Elixirでは,`do`/`end`ブロックは式のまとまりを簡単に`do:`へ渡すためのものです.これらは同じことを表しています: + In Elixir, `do`/`end` blocks are a convenience for passing a group of expressions to `do:`. These are equivalent: ```iex @@ -225,6 +307,8 @@ iex> if true, do: ( 13 ``` +2番目の構文は**キーワードリスト**を使っていると言っています.`else`も同じ構文で渡せます: + We say the second syntax is using **keyword lists**. We can pass `else` using this syntax: ```iex @@ -232,6 +316,8 @@ iex> if false, do: :this, else: :that :that ``` +`do`/`end`ブロックを使う際には小さな,しかし重要な点に気をつけてください: ブロックは常に一番遠くの関数呼び出しに束縛されます.例えば,以下の式 + It is important to keep one small detail in mind when using `do`/`end` blocks: they always bind to the farthest function call. For example, the following expression: ```iex @@ -240,6 +326,8 @@ iex> is_number if true do ...> end ``` +はこのように解釈されます: + Would be parsed as: ```iex @@ -248,6 +336,8 @@ iex> is_number(if true) do ...> end ``` +そうするとElixirは`is_number/2`を呼び出そうとして未定義関数エラーになります.あいまいさを解消するのには明示的に括弧を追加すると良いです: + Which leads to an undefined function error as Elixir attempts to invoke `is_number/2`. Adding explicit parentheses is enough to resolve the ambiguity: ```iex @@ -257,4 +347,6 @@ iex> is_number(if true do true ``` +キーワードリストはこの言語においてとても重要な役割を担っており,様々な関数やマクロにおいてあたりまえの存在です.後の章でこのことをもう少し詳しくみていきます.今は"バイナリ,文字列そして文字リスト"について話していきましょう. + Keyword lists play an important role in the language and are quite common in many functions and macros. We will explore them a bit more in a future chapter. Now it is time to talk about "Binaries, strings and char lists". From 3eba3c7d63f266092ab0cdc6fd1be89a78d40577 Mon Sep 17 00:00:00 2001 From: niku Date: Thu, 3 Apr 2014 15:15:14 +0900 Subject: [PATCH 06/15] Translate into japanese(6 Binaries, strings and char lists) --- getting_started/6.markdown | 60 +++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/getting_started/6.markdown b/getting_started/6.markdown index f7470d717..876ead7a0 100644 --- a/getting_started/6.markdown +++ b/getting_started/6.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 6 Binaries, strings and char lists +title: 6 バイナリ,文字列そして文字リスト - Binaries, strings and char lists guide: 6 --- @@ -8,6 +8,8 @@ guide: 6
+"基本的な型"のなかで,文字列について学び,チェックするのに`is_binary/1`を使いました: + In "Basic Types", we learned about strings and used the `is_binary/1` function for checks: ```iex @@ -17,16 +19,26 @@ iex> is_binary string true ``` +この章をすすめるとバイナリとは何か,文字列とはどういう関係か,`'このように'`単一引用符でくくられた値はElixirではどういう意味を持つかについてわかるようになります. + In this chapter, we will understand what binaries are, how they associate with strings, and what a single-quoted value, `'like this'`, means in Elixir. -## 6.1 UTF-8 and Unicode +## 6.1 UTF-8とUnicode - UTF-8 and Unicode + +文字列はUTF-8でエンコードされたバイナリです.それが実際にどういう意味なのかわかるためには,バイトとコードポイントの違いについて知らなくてはなりません. A string is a UTF-8 encoded binary. In order to understand exactly what we mean by that, we need to understand the difference between bytes and code points. +ユニコード標準では,コードポイントを私たちが知っている多くの文字へ割り当てています.例えば文字`a`は`97`というコードポイントを持っていますし,同じように文字`ł`は`322`というコードポイントを持っています.ディスクへ文字列`"hełło"`と書くとき,このコードポイントをバイトへ変換しなければなりません.もし1つのコードポイントを1バイトで表現するという方針だった場合`"hełło"`と書けません.なぜなら`ł`のコードポイントは`322`であり,1バイトでは`0`から`255`までしか表現できないからです.しかしあなたのスクリーンでは`"hełło"`が読めてますよね,それは*謎の技術*で表現されているためです .それがエンコーディングというものができた理由です. + The Unicode standard assigns code points to many of the characters we know. For example, the letter `a` has code point `97` while the letter `ł` has code point `322`. When writing the string `"hełło"` to disk, we need to convert this code point to bytes. If we adopted a rule that said one byte represents one code point, we wouldn't be able to write `"hełło"`, because it uses the code point `322` for `ł`, and one byte can only represent a number from `0` to `255`. But of course, given you can actually read `"hełło"` on your screen, it must be represented *somehow*. That's where encodings come in. +バイトでコードポイントを表現する場合,どうにかエンコードしなければなりません.ElixirではデフォルトのエンコーディングとしてUTF-8エンコーディングを選びました.文字列はUTF-8でエンコードされたバイナリであるというときに意味するところは,文字列はコードポイントをある規則にのっとって表現しているバイトの集まりであり,その規則とはUTF-8エンコーディングであるということです. + When representing code points in bytes, we need to encode them somehow. Elixir chose the UTF-8 encoding as its main and default encoding. When we say a string is a UTF-8 encoded binary, we mean a string is a bunch of bytes organized in a way to represent certain code points, as specified by the UTF-8 encoding. +コードポイントが`322`に割り当たっている`ł`のような場合,表現するには1バイトより多くのバイトが必要です.それが文字列を`byte_size/1`で計算したときと`String.length/1`で計算したときの違いになっています: + Since we have code points like `ł` assigned with the number `322`, we actually need more than one byte to represent it. That's why we see a difference when we calculate the `byte_size/1` of a string compared to its `String.length/1`: ```iex @@ -38,6 +50,8 @@ iex> String.length string 5 ``` +UTF-8では`h`,`e`や`o`を表現するには1バイトですみますが,`ł`を表現するには2バイト必要です.Elixirでは`?`を使うとコードポイントの値を得ることができます: + UTF-8 requires one byte to represent the code points `h`, `e` and `o`, but two bytes to represent `ł`. In Elixir, you can get a code point's value by using `?`: ```iex @@ -47,6 +61,8 @@ iex> ?ł 322 ``` +[`String`モジュール](/docs/stable/elixir/String.html)の関数を使うとコードポイント毎に文字を分けることもできます: + You can also use the functions in [the `String` module](/docs/stable/elixir/String.html) to split a string in its code points: ```iex @@ -54,11 +70,17 @@ iex> String.codepoints("hełło") ["h", "e", "ł", "ł", "o"] ``` +これからElixirで文字列を扱うのに素晴しいサポートがあることがわかっていくことでしょう.ユニコード文字の操作も多数サポートしています.実際,Elixirは["The string type is broken"](http://mortoray.com/2013/11/27/the-string-type-is-broken/)の記事に挙げられている例をテストして全て合格しています. + You will see that Elixir has excellent support for working with strings. It also supports many of the Unicode operations. In fact, Elixir passes all the tests showcased in the ["The string type is broken"](http://mortoray.com/2013/11/27/the-string-type-is-broken/) article. +ともあれ文字列はこの物語の一部にすぎません.文字列はバイナリであり,私たちは(文字列へ)関数`is_binary/1`を使いました,Elixirには文字列へ能力を与えている隠れた型がなくてはなりません.そして,やはりあります.さあバイナリについて話しましょう! + However, strings are just part of the story. If a string is a binary, and we have used the `is_binary/1` function, Elixir must have an underlying type empowering strings. And it does. Let's talk about binaries! -## 6.2 Binaries (and bitstrings) +## 6.2 バイナリ(とビット列) - Binaries (and bitstrings) + +Elixirではバイナリを`<<>>`を使って定義することができます: In Elixir, you can define a binary using `<<>>`: @@ -69,6 +91,8 @@ iex> byte_size <<0, 1, 2, 3>> 4 ``` +バイナリは単なるバイトの連なりです.もちろん,これらのバイトは何らかの方法で整理されています,文字列としては妥当ではないこともあります: + A binary is just a sequence of bytes. Of course, those bytes can be organized in any way, even in a sequence that does not make them a valid string: ```iex @@ -76,6 +100,8 @@ iex> String.valid?(<<239, 191, 191>>) false ``` +文字列の結合操作とは実はバイナリの結合操作です: + The string concatenation operation is actually a binary concatenation operator: ```iex @@ -83,6 +109,8 @@ iex> <<0, 1>> <> <<2, 3>> <<0, 1, 2, 3>> ``` +ヌルバイト``<<0>>`を結合させて文字列のバイナリ表現を見ることはElixirにおいて一般的な技法です: + A common trick in Elixir is to concatenate the null byte `<<0>>` to a string to see its inner binary representation: ```iex @@ -90,6 +118,8 @@ iex> "hełło" <> <<0>> <<104, 101, 197, 130, 197, 130, 111, 0>> ``` +バイナリに書かれているそれぞれの番号は1バイトの表現なので255まであります.(複数の)バイナリは255より大きい数を保持したり,コードポイントからUTF8表現へ変換したりできます: + Each number given to a binary is meant to represent a byte and therefore must go up to 255. Binaries allow modifiers to be given to store numbers bigger than 255 or to convert a code point to its utf8 representation: ```iex @@ -105,6 +135,8 @@ iex> <<256 :: utf8, 0>> <<196, 128, 0>> ``` +もしバイトが8ビットなら,1ビットを渡したらどうなるでしょうか? + If a byte has 8 bits, what happens if we pass a size of 1 bit? ```iex @@ -120,8 +152,12 @@ iex> bit_size(<< 1 :: size(1)>>) 1 ``` +値はもはやバイナリではありませんがビット列ではあります -- 単なるビットの集まり!つまりバイナリとは8で割り切れる数のビット列のことです! + The value is no longer a binary, but a bitstring -- just a bunch of bits! So a binary is a bitstring where the number of bits is divisible by 8! +バイナリ/ビット列にもパターンマッチできます: + We can also pattern match on binaries / bitstrings: ```iex @@ -133,6 +169,8 @@ iex> <<0, 1, x>> = <<0, 1, 2, 3>> ** (MatchError) no match of right hand side value: <<0, 1, 2, 3>> ``` +バイナリの全てのエントリーはちょうど8bitずつを期待していることに注意してください.しかしバイナリ修飾子を使うことで「残り」へマッチさせることができます: + Note each entry in the binary is expected to match exactly 8 bits. However, we can match on the rest of the binary modifier: ```iex @@ -142,6 +180,8 @@ iex> x <<2, 3>> ``` +上のパターンは`<<>>`の最後がバイナリであるときにだけ動作します.文字列結合演算子`<>`の使いかたに似ていますね: + The pattern above only works if the binary is at the end of `<<>>`. Similar results can be retrieved with the string concatenation operator `<>`: ```iex @@ -151,9 +191,13 @@ iex> rest "llo" ``` +ビット列,バイナリや文字列をめぐる旅も終わりです.文字列はUTF-8でエンコードされたバイナリのことで,バイナリは8で割り切れる数のビット列の集まりです.ここではElixirがビットとバイトを柔軟に扱える機能を提供していることをお見せしましたが,実際にはバイナリで作業する時間のうち99%はそのままバイナリとして扱い,`is_binary/1`と`byte_size/1`の関数を使うことになるでしょう. + This finishes our tour of bitstrings, binaries and strings. A string is a UTF-8 encoded binary, and a binary is a bitstring where the number of bits is divisible by 8. Although this shows the flexibility Elixir provides to work with bits and bytes, 99% of the time you will be working with binaries and using the `is_binary/1` and `byte_size/1` functions. -## 6.3 Char lists +## 6.3 文字リスト - Char lists + +文字リストは文字のリストでしかありません: A char list is nothing more than a list of characters: @@ -166,8 +210,12 @@ iex> 'hello' 'hello' ``` +ご覧のとおり,単一引用符で囲まれた文字列はバイト列のかわりにコードポイントのリストを含んでいます(iexではASCIIの範囲より外にある文字を含んでいると,コードポイントの数字しか表示しないことに注意してください).二重引用符で囲まれたものは文字列(つまりバイナリ)で,単一引用符で囲まれたものは文字のリスト(つまりリスト)です. + You can see that, instead of containing bytes, a char list contains the code points of the characters in between single-quotes (note that iex will only output code points if any of the chars is outside the ASCII range). So while double-quotes represent a string (i.e. a binary), single-quotes represents a char list (i.e. a list). +実際には文字リストはほとんどErlangとのインターフェース,特にバイナリを引数に取れない古いライブラリに使われています.`to_string/1`や`to_char_list/1`関数を使うと文字リストを文字列に変換したりその逆のことができます: + In practice, char lists are used mostly when interfacing with Erlang, in particular old libraries that do not accept binaries as arguments. You can convert a char list to a string and back by using the `to_string/1` and `to_char_list/1` functions: ```iex @@ -181,6 +229,10 @@ iex> to_string 1 "1" ``` +それらの関数はポリモーフィックであることに注目してください.文字リストを文字列の変換だけではなく,整数から文字列,アトムから文字列などの変換にも使えます. + Note that those functions are polymorphic. They not only convert char lists to strings, but also integers to strings, atoms to strings, and so on. +バイナリ,文字列そして文字リストの話題から離れて,キーバリューデータ構造について話していくことにしましょう. + With binaries, strings, and char lists out of the way, it is time to talk about key-value data structures. From 043fd261704ae8f8fb92e67ea27aa659167c81d6 Mon Sep 17 00:00:00 2001 From: niku Date: Sat, 5 Apr 2014 11:47:15 +0900 Subject: [PATCH 07/15] Translate into japanese(7 Keywords, maps and dicts) --- getting_started/7.markdown | 78 +++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/getting_started/7.markdown b/getting_started/7.markdown index c8c2fddf4..269c77b9b 100644 --- a/getting_started/7.markdown +++ b/getting_started/7.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 7 Keywords, maps and dicts +title: 7 キーワード,マップそしてリスト - Keywords, maps and dicts guide: 7 --- @@ -8,11 +8,17 @@ guide: 7
+ある値(あるいは複数の値)をキーにできるデータ構造,すなわち連想データ構造のことについてはまだ何も話していませんね.他の言語では例えばディクショナリ,ハッシュ,連想配列,マップなどと呼ばれているもののことです. + So far we haven't discussed any associative data structures, i.e. data structures that are able to associate a certain value (or multiple values) to a key. Different languages call these different names like dictionaries, hashes, associative arrays, maps, etc. +Elixirにはキーワードリストとマップという2つの主な連想データ構造があります.これからそれらについて学んでいきましょう! + In Elixir, we have two main associative data structures: keyword lists and maps. It's time to learn more about them! -## 7.1 Keyword lists +## 7.1 キーワードリスト - Keyword lists + +多くの関数型言語では,連想データ構造の表現を2要素のタプルをリストにしたものを使うことが一般的です.Elixirでは,最初の要素(つまりキー)がアトムとなっているタプルのリストがある場合に,それをキーワードリストと呼びます: In many functional programming languages, it is common to use a list of 2-item tuples as the representation of an associative data structure. In Elixir, when we have a list of tuples and the first item of the tuple (i.e. the key) is an atom, we call it a keyword list: @@ -25,8 +31,12 @@ iex> list[:a] 1 ``` +上で見たように,エリクサーはこのようなリストを定義するのに特別な構文をサポートしており,裏ではタプルのリストへと変えています.これらは単なるリストなので,キーワードリストはリストへ行う操作がどれも可能で,また性能の特徴も同じです. + As you can see above, Elixir supports a special syntax for defining such lists, and underneath they just map to a list of tuples. Since they are simply lists, all operations available to lists, including their performance characteristics, also apply to keyword lists. +例えば`++`を使ってキーワードリストへ新しい値を追加することができます: + For example, we can use `++` to add new values to a keyword list: ```iex @@ -36,6 +46,8 @@ iex> [a: 0] ++ list [a: 0, a: 1, b: 2] ``` +値を取るときは前にある方が取得されることに注意してください: + Note that values added to the front are the ones fetched on lookup: ```iex @@ -45,11 +57,18 @@ iex> new_list[:a] 0 ``` +キーワードリストは2つの特別な特徴があるため重要です: + Keyword lists are important because they have two special characteristics: +* キーの順序を開発者が与えたとおりに保持する +* キーを複数回与えることができる + * They keep the keys ordered as given by the developer. * They allow a key to be given more than once. +例えば,[Ectoライブラリ](https://github.com/elixir-lang/ecto)ではデータベースクエリーを洗練されたDSLで書けるようにするために2つの機能両方を使っています: + For example, [the Ecto library](https://github.com/elixir-lang/ecto) makes use of both features to provide an elegant DSL for writing database queries: ```elixir @@ -59,6 +78,8 @@ query = from w in Weather, select: w ``` +この特徴があるため,キーワードリストは関数へオプションを渡すためのデフォルトのメカニズムとなっています.5章では`if/2`マクロについて話しましたね,以下のような構文をサポートしていたのでした: + Those features are what prompted keyword lists to be the default mechanism for passing options to functions in Elixir. In chapter 5, when we discussed the `if/2` macro, we mentioned the following syntax is supported: ```iex @@ -66,6 +87,8 @@ iex> if false, do: :this, else: :that :that ``` +`do`と`else`の組はキーワードリストです!事実この呼び出しは次と同じです: + The `do:` and `else:` pairs are keyword lists! In fact, the call above is equivalent to: ```iex @@ -73,10 +96,16 @@ iex> if(false, [do: :this, else: :that]) :that ``` +一般的に,キーワードリストは関数の引数の最後にあり,角括弧はつけてもつけなくてもいいです. + In general, when the keyword list is the last argument of a function, the square brackets are optional. +キーワードリストを操作するために,Elixirは[`Keyword`モジュール](/docs/stable/elixir/Keyword.html)を提供しています.キーワードリストは単にリストであることを思い出してください,そのためリストと同じ線形の性能特性をもっています.より長いリストは,キーを見つけるのがより長くなり,要素を数えるのがより長くなり,などなど.そのため,キーワードリストは主にオプションとして使われています.もし沢山の要素を保持しなければならなかったり,1つのキーが多くとも1つの値しか持たないことが保証したいなら,かわりにマップを使うべきです. + In order to manipulate keyword lists, Elixir provides [the `Keyword` module](/docs/stable/elixir/Keyword.html). Remember though keyword lists are simply lists, and as such they provide the same linear performance characteristics as lists. The longer the list, the longer it will take to find a key, to count the number of items, and so on. For this reason, keyword lists are used in Elixir mainly as options. If you need to store many items or guarantee one-key associates with at maximum one-value, you should use maps instead. +キーワードリストにもパターンマッチできます: + Note we can also pattern match on keyword lists: ```iex @@ -90,9 +119,13 @@ iex> [b: b, a: a] = [a: 1, b: 2] ** (MatchError) no match of right hand side value: [a: 1, b: 2] ``` +ともあれ,パターンマッチにアイテムの数やマッチの順番を必要とするようなリストへパターンマッチすることはほとんどないでしょう. + However this is rarely done in practice since pattern matching on lists require the number of items and their order to match. -## 7.2 Maps +## 7.2 マップ - Maps + +あなたがキーバリューストアが必要をするとき,マップはElixirにおける"go to"データ構造です.マップは`%{}`を使うと作ることができます: Whenever you need a key-value store, maps are the "go to" data structure in Elixir. A map is created using the `%{}` syntax: @@ -105,11 +138,18 @@ iex> map[2] :b ``` +キーワードリストに比べて,すでに2つ違う点がありますね: + Compared to keyword lists, we can already see two differences: +* マップはキーをどんな値にもできる +* マップのキーは順番通りにならない + * Maps allow any value as key. * Maps' keys do not follow any ordering. +もしマップを作るときに同じキーを渡すと,最後の一つが勝ちます: + If you pass duplicate keys when creating a map, the last one wins: ```iex @@ -117,6 +157,8 @@ iex> %{1 => 1, 1 => 2} %{1 => 2} ``` +マップのキーが全てアトムの場合は便利なキーワード構文を使うことができます: + When all the keys in a map are atoms, you can use the keyword syntax for convenience: ```iex @@ -124,6 +166,8 @@ iex> map = %{a: 1, b: 2} %{a: 1, b: 2} ``` +キーワードリストとは対照的に,マップはパターンマッチングに使いやすいです: + In contrast to keyword lists, maps are very useful with pattern matching: ```iex @@ -137,8 +181,12 @@ iex> %{:c => c} = %{:a => 1, 2 => :b} ** (MatchError) no match of right hand side value: %{2 => :b, :a => 1} ``` +上でみたように,マップは与えられたマップのキーがある部分にだけマッチします.したがって,空のマップは全てのマップにマッチします. + As shown above, a map matches as long as the given keys exist in the given map. Therefore, an empty map matches all maps. +マップの興味深い特質に更新やアトムのキーにアクセスするための特定の構文が提供されているところがあります: + One interesting property about maps is that they provide a particular syntax for updating and accessing atom keys: ```iex @@ -152,18 +200,30 @@ iex> %{map | :c => 3} ** (ArgumentError) argument error ``` +上にあるアクセスと更新のどちらの構文でも既にあるキーを必要とします.例えば最後の行ではマップに`c`がないので失敗しています.これはマップに既にキーがあることをあなたが期待している場合にすごく便利に使うことができます. + Both access and update syntaxes above require the given keys to exist. For example, the last line failed because there is no `:c` in the map. This is very useful when you are working with maps where you only expect certain keys to exist. +後の章で,私たちはコンパイル時の保証やエリクサーのポリモーフィズムの基礎となる構造体について学びます.構造体は上で書いたような更新の保証が便利であることがわかっているマップの上に構築されています. + In future chapters, we will also learn about structs, which provide compile-time guarantees and the foundation for polymorphism in Elixir. Structs are built on top of maps where the update guarantees above are proven to be quite useful. +マップを操作するには[`Map`モジュール](/docs/stable/elixir/Map.html)を使います,APIは`Keyword`モジュールに良く似ています.どちらも`Dict`という振舞いを実装しているためです. + Manipulating maps is done via [the `Map` module](/docs/stable/elixir/Map.html), it provides a very similar API to the `Keyword` module. This is because both modules implement the `Dict` behaviour. +> メモ: マップは最近[EEP 43](http://www.erlang.org/eeps/eep-0043.html)でErlang VMに導入されました.Erlang 17はEEPの実装の一部,"small maps"だけのサポートを提供しています.これは最大数ダース程度のキーを持つマップの場合にだけ性能が良いことを意味しています.この溝を埋めるため,Elixirでは数十万のキーでも性能が良いアルゴリズムを利用する[`HashDict`モジュール](/docs/stable/elixir/HashDict.html)も提供しています. + > Note: Maps were recently introduced into the Erlang VM with [EEP 43](http://www.erlang.org/eeps/eep-0043.html). Erlang 17 provides a partial implementation of the EEP, where only "small maps" are supported. This means maps have good performance characteristics only when storing at maximum a couple of dozens keys. To fill in this gap, Elixir also provides [the `HashDict` module](/docs/stable/elixir/HashDict.html) which uses a hashing algorithm to provide a dictionary that supports hundreds of thousands keys with good performance. -## 7.3 Dicts +## 7.3 ディクショナリ - Dicts + +エリクサーではキーワードリストとマップのどちらもディクショナリと呼ばれています.言いかえると,ディクショナリはインターフェースのようなもの(Elixirではビヘイビアと呼んでいます)で,キーワードリストもマップのどちらのモジュールもこのインターフェースを実装しています. In Elixir, both keyword lists and maps are called dictionaries. In other words, a dictionary is like an interface (we call them behaviours in Elixir) and both keyword lists and maps modules implement this interface. +このインターフェースはAPIを提供(実際の実装は移譲)している[`Dict`モジュール](/docs/stable/elixir/Dict.html)で定義されています. + This interface is defined in the [the `Dict` module](/docs/stable/elixir/Dict.html) module which also provides an API that delegates to the underlying implementations: ```iex @@ -177,10 +237,18 @@ iex> Dict.put(map, :a, 1) %{a: 1} ``` +`Dict`モジュールは,開発者が`Dict`の特徴を持った実装を行え,既存のElixirコードで使えるようにします.`Dict`モジュールは他のディクショナリ同士でも動作するような関数も提供しています.例えば`Dict.equal?/2`はどんな種類の2つのディクショナリであっても比較できます. + The `Dict` module allows any developer to implement their own variation of `Dict`, with specific characteristics, and hook into existing Elixir code. The `Dict` module also provides functions that are meant to work across dictionaries. For example, `Dict.equal?/2` can compare two dictionaries of any kind. -That said, you may be wondering, which of `Keyword`, `Map` or `Dict` modules should you use in your code? The answer is: it depends. +そうすると,`Keyword`,`Map`や`Dict`のどのモジュールを使うべきなのかなあ?と思うでしょう.答えは: 場合によるです. + +that said, you may be wondering, which of `Keyword`, `Map` or `Dict` modules should you use in your code? The answer is: it depends. + +もしあなたのコードが引数としてキーワードを期待しているなら,明示的に`Keyword`モジュールを使いましょう.もしあなたがmapを操作するなら`Map`モジュールを使いましょう.しかしながら,どのディクショナリでも動作するようなAPIの場合は`Dict`モジュールを使いましょう(そして異なるディクショナリ実装を引数に渡してテストをパスすることも確かめておきましょう). If your code is expecting a keyword as an argument, explicitly use the `Keyword` module. If you want to manipulate a map, use the `Map` module. However, if your API is meant to work with any dictionary, use the `Dict` module (and make sure to write tests that pass different dict implementations as arguments). +Elixirでの関連データ構造の説明はおしまいです.あなたはこれで連想データ構造を必要とする問題に取り組むための適切なツール,キーワードリストとマップを持つことになりました. + This concludes our introduction to associative data structures in Elixir. You will find out that given keyword lists and maps, you will always have the right tool to tackle problems that require associative data structures in Elixir. From 752415e8655fb554f8a0bf6897539ae191e8fdc4 Mon Sep 17 00:00:00 2001 From: niku Date: Tue, 8 Apr 2014 12:48:50 +0900 Subject: [PATCH 08/15] Translate into japanese(8 Modules) --- getting_started/8.markdown | 66 ++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/getting_started/8.markdown b/getting_started/8.markdown index f81437eec..1eb5fc3fa 100644 --- a/getting_started/8.markdown +++ b/getting_started/8.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 8 Modules +title: 8 モジュール - Modules guide: 8 --- @@ -8,6 +8,8 @@ guide: 8
+Elixirではモジュールのなかに複数の関数を入れてグループ化します.以前の章で既にいくつものモジュールを使ってきました.例えば[`String`モジュール](/docs/stable/elixir/String.html)をこんな感じに: + In Elixir we group several functions into modules. We've already used many different modules in the previous chapters like [the `String` module](/docs/stable/elixir/String.html): ```iex @@ -15,6 +17,8 @@ iex> String.length "hello" 5 ``` +自分達でモジュールを作るには`defmodule`マクロを使います.そのマクロの中で`def`マクロを使って関数を定義します: + In order to create our own modules in Elixir, we use the `defmodule` macro. We use the `def` macro to define functions in that module: ```iex @@ -28,9 +32,13 @@ iex> Math.sum(1, 2) 3 ``` +この後の節では例がもうちょっと複雑になり,シェルから入力するにはすごく注意しなければなりません.この機会に,どうやってElixirのコードをコンパイルするか,どうやってElixirのスクリプトを実行するかを学びましょう. + In the following sections, our examples are going to get a bit more complex, and it can be tricky to type them all in the shell. It's about time for us to learn how to compile Elixir code and also how to run Elixir scripts. -## 8.1 Compilation +## 8.1 コンパイル - Compilation + +モジュールをファイルへ書くことの便利さの多くは,それがコンパイルできて再利用できるところにあります.今,ファイルの名前が`math.ex`で,以下の内容が書いてあるとしましょう: Most of the time it is convenient to write modules into files so they can be compiled and reused. Let's assume we have a file named `math.ex` with the following contents: @@ -42,10 +50,14 @@ defmodule Math do end ``` +このファイルは`elixirc`を使ってコンパイルできます: + This file can be compiled using `elixirc`: elixirc math.ex +こうすると,定義されたモジュールのバイトコードを含む`Elixir.Math.beam`という名前のファイルが生成されるでしょう.もう一度`iex`を開始すると,定義したモジュールが使えるようになっています(`iex`が開始したときに同じディレクトリにあるバイトコードファイルは自動的に読み込まれます): + This will generate a file named `Elixir.Math.beam` containing the bytecode for the defined module. If we start `iex` again, our module definition will be available (provided that `iex` is started in the same directory the bytecode file is in): ```iex @@ -53,15 +65,25 @@ iex> Math.sum(1, 2) 3 ``` +Elixirは通常3つのディレクトリを備えています: + Elixir projects are usually organized into three directories: +* ebin - コンパイルされたバイトコードが入っています +* lib - Elixirのコードが入っています(たいてい`.ex`というファイルです) +* test - テストが入っています(たいて`.exs`というファイルです) + * ebin - contains the compiled bytecode * lib - contains elixir code (usually `.ex` files) * test - contains tests (usually `.exs` files) +実際のプロジェクトでは,`mix`というビルドツールがコンパイルと適切なパスのセッティングをうまくやってくれます.学習目的のため,Elixirではコンパイル成果物を作らずに融通がきくスクリプトモードというものを使えます. + When working on actual projects, the build tool called `mix` will be responsible for compiling and setting up the proper paths for you. For learning purposes, Elixir also supports a scripted mode which is more flexible and does not generate any compiled artifacts. -## 8.2 Scripted mode +## 8.2 スクリプトモード - Scripted mode + +`.ex`というElixirの拡張子の他に,スクリプティング用に`.exs`というファイルも使えます.Elixirは2つのファイルを同じように扱います,違いは意図だけです.`.ex`ファイルはコンパイルされることを意図しています,一方`.exs`はコンパイル不要でスクリプティングに使われます.例えば`math.exs`と呼ばれているファイルを作ることができ: In addition to the Elixir file extension `.ex`, Elixir also supports `.exs` files for scripting. Elixir treats both files exactly the same way, the only difference is in intention. `.ex` files are meant to be compiled while `.exs` files are used for scripting, without the need for compilation. For instance, we can create a file called `math.exs`: @@ -75,13 +97,19 @@ end IO.puts Math.sum(1, 2) ``` +そしてこのように実行できます: + And execute it as: elixir math.exs +ファイルはメモリ内でコンパイルされ,実行され,結果として3を表示します.バイトコードファイルは作られません.今後の例では,上で見たようにスクリプトファイルへコードを書いて実行することをおすすめします. + The file will be compiled in memory and executed, printing "3" as the result. No bytecode file will be created. In the following examples, we recommend you write your code into script files and execute them as shown above. -## 8.3 Named functions +## 8.3 名前付き関数 - Named functions + +モジュールのなかで,`def/2`を使って関数を定義したり`defp/2`を使ってプライベート関数を定義できます.`def/2`で定義した関数は別のモジュールから呼び出せるのに対し,プライベート関数はモジュールの中だけでしか呼び出せません. Inside a module, we can define functions with `def/2` and private functions with `defp/2`. A function defined with `def/2` can be invoked from other modules while a private function can only be invoked locally. @@ -100,6 +128,8 @@ Math.sum(1, 2) #=> 3 Math.do_sum(1, 2) #=> ** (UndefinedFunctionError) ``` +関数宣言はガードと複数句に対応しています.もし関数に複数の句がある場合,Elixirはマッチする句があるまで順番に試していきます.引数が0かそうではないかをチェックする関数はこうなります: + Function declarations also support guards and multiple clauses. If a function has several clauses, Elixir will try each clause until it finds one that matches. Here is an implementation of a function that checks if the given number is zero or not: ```elixir @@ -120,9 +150,13 @@ Math.zero?([1,2,3]) #=> ** (FunctionClauseError) ``` +引数がどの句にもマッチしなかった場合はエラーが発生します. + Giving an argument that does not match any of the clauses raises an error. -## 8.4 Function capturing +## 8.4 関数のキャプチャ - Function capturing + +このチュートリアルのあいだ,関数を指すのに`name/arity`という記法を使ってきました.実はこの記法を名前付き関数の型として使うこともできます.`iex`を開始して上で定義した`math.exs`を動かしてみましょう: Throughout this tutorial, we have been using the notation `name/arity` to refer to functions. It happens that this notation can actually be used to retrieve a named function as a function type. Let's start `iex` and run the `math.exs` file defined above: @@ -139,6 +173,8 @@ iex> fun.(0) true ```` +`is_function/1`のような,ローカルな関数やインポートされた関数はモジュールをつけなくてもキャプチャできます: + Local or imported functions, like `is_function/1`, can be captured without the module: ```iex @@ -148,6 +184,8 @@ iex> (&is_function/1).(fun) true ``` +キャプチャ構文は関数を作るときのショートカットとしても使えます: + Note the capture syntax can also be used as a shortcut for creating functions: ```iex @@ -157,9 +195,13 @@ iex> fun.(1) 2 ``` +`&1`は関数に渡された最初の引数を表します.上の`&(&1+1)`は`fn x -> x + 1 end`と同じです.この構文は短い関数定義をするのに便利です.キャプチャ演算子`&`については[`Kernel.SpecialForms`のドキュメント](/docs/stable/elixir/Kernel.SpecialForms.html)で詳しく読むことができます. + The `&1` represents the first argument passed into the function. `&(&1+1)` above is exactly the same as `fn x -> x + 1 end`. The syntax above is useful for short function definitions. You can read more about the capture operator `&` in [the `Kernel.SpecialForms` documentation](/docs/stable/elixir/Kernel.SpecialForms.html). -## 8.5 Default arguments +## 8.5 デフォルト引数 - Default arguments + +名前つき関数ではデフォルト引数も使えます: Named functions in Elixir also support default arguments: @@ -174,6 +216,8 @@ IO.puts Concat.join("Hello", "world") #=> Hello world IO.puts Concat.join("Hello", "world", "_") #=> Hello_world ``` +デフォルト値としてどんな式も用意しておけますが,関数定義のときには評価されません; 後で使うため単に保存しします.関数が呼び出され,その関数のデフォルト値が利用されるたび,デフォルト値の式が評価されます. + Any expression is allowed to serve as a default value, but it won't be evaluated during the function definition; it will simply be stored for later use. Every time the function is invoked and any of its default values have to be used, the expression for that default value will be evaluated: ```elixir @@ -192,6 +236,8 @@ hello :ok ``` +もしデフォルト値つきの関数に複数の句がある場合,デフォルト値を宣言する(動作内容を含めない)ヘッダ部分を分けて作っておくことをおすすめします: + If a function with default values has multiple clauses, it is recommended to create a function head (without an actual body), just for declaring defaults: ```elixir @@ -212,6 +258,8 @@ IO.puts Concat.join("Hello", "world", "_") #=> Hello_world IO.puts Concat.join("Hello") #=> Hello ``` +もしデフォルト値を使うなら,関数定義の上書きについてだけは十分に注意しなければなりません.以下の例を考えてみましょう: + When using default values, one must be careful to avoid overlapping function definitions. Consider the following example: ```elixir @@ -228,10 +276,14 @@ defmodule Concat do end ``` +上のコードを"concat.ex"というファイル名でセーブしコンパイルすると,Elixirは以下の警告を出力するでしょう: + If we save the code above in a file named "concat.ex" and compile it, Elixir will emit the following warning: concat.exs:7: this clause cannot match because a previous clause at line 2 always matches +2引数の`join`関数は常に最初の`join`定義を呼び出すことになり,一方2番目のものは3つの引数が渡されたときにしか呼び出されませんということをコンパイラが私たちへ教えてくれています: + The compiler is telling us that invoking the `join` function with two arguments will always choose the first definition of `join` whereas the second one will only be invoked when three arguments are passed: $ iex concat.exs @@ -248,4 +300,6 @@ iex> Concat.join "Hello", "world", "_" "Hello_world" ``` +モジュールの簡単な導入はおしまいです.次の章では名前つき関数を再帰に使うにはどうすればよいか学び,他のモジュールから関数を導入するのに使われるレキシカルディレクティブを調査し,モジュールの属性について話すことにします. + This finishes our short introduction to modules. In the next chapters, we will learn how to use named functions for recursion, explore Elixir lexical directives that can be used for importing functions from other modules and discuss module attributes. From 85e01674f58f8fb89d4e927c71700335f6896b26 Mon Sep 17 00:00:00 2001 From: niku Date: Thu, 10 Apr 2014 21:11:17 +0900 Subject: [PATCH 09/15] Translate into japanese(9 Recursion) --- getting_started/9.markdown | 41 +++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/getting_started/9.markdown b/getting_started/9.markdown index 08e23ad97..91fc85569 100644 --- a/getting_started/9.markdown +++ b/getting_started/9.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 9 Recursion +title: 9 再帰 - Recursion guide: 9 --- @@ -8,6 +8,8 @@ guide: 9
+イミュータブル(不変)という性質を持つため,Elixir(や関数型言語)でのループは従来の手続き型言語とは異なる書き方をします.例えば,手続き型ではこんな感じで書くでしょう: + Due to immutability, loops in Elixir (and in functional programming languages) are written differently from conventional imperative languages. For example, in an imperative language, one would write: ```c @@ -16,6 +18,9 @@ for(i = 0; i < array.length; i++) { } ``` +上の例では配列と補助変数`i`を変化させています.Elixirではこうできません.そのかわり関数型言語は再帰に頼ります: 関数は再帰的に呼び出され,停止の条件になるまで,動作し続けます.任意の回数文字を出力する以下の例を考えてみましょう: + + In the example above, we are mutating the array and the helper variable `i`. That's not possible in Elixir. Instead, functional languages rely on recursion: a function is called recursively until a condition is reached that stops the recursive action from continuing. Consider the example below that prints a string an arbitrary amount of times: ```elixir @@ -36,18 +41,32 @@ Recursion.print_multiple_times("Hello!", 3) # Hello! ``` +caseと似たように,関数は複数の句を持つことができます.関数へ渡した引数が句のパターンとマッチし,ガードが`true`と評価される,特定の1つの句が実行されます. + Similar to case, a function may have many clauses. A particular clause is executed when the arguments passed to the function match the clause's argument patterns and its guard evaluates to `true`. +上の`print_multiple_times/2`が最初に呼ばれたとき,引数`n`は`3`になっています. + Above when `print_multiple_times/2` is initially called, the argument `n` is equal to `3`. +最初の句は`n`が`1`と同じか小さいときにこの定義を使ってくださいというガードを持っています.そうではないため,Elixirは次の句の定義へと移ります. + The first clause has a guard which says use this definition if and only if `n` is less than or equal to `1`. Since this is not the case, Elixir proceeds to the next clause's definition. +2番目の定義はパターンにマッチし,ガードもありませんので,これが実行されます.最初に`msg`を表示し,次に2番目の引数へ`n-1`(`2`)を渡して自分自身を呼び出します.そうすると`msg`が表示され,再び`print_multiple_times/2`が呼び出されます.このとき2番目の引数は`1`になります. + The second definition matches the pattern and has no guard so it will be executed. It first prints our `msg` and then calls itself passing `n - 1` (`2`) as the second argument. Our `msg` is printed and `print_multiple_times/2` is called again this time with the second argument set to `1`. +`n`が`1`になったことにより,`print_multiple_times/2`にある1番目の定義のガードが真と評価されるので,この定義を実行します.`msg`が表示され,あとは何もすることが残っていません. + Because `n` is now set to `1`, the guard to our first definition of `print_multiple_times/2` evaluates to true, and we execute this particular definition. The `msg` is printed, and there is nothing left to execute. +引数の2番目へどんな数を渡されても,1番目の定義("ベースケース"と呼ばれています),あるいはベースケースへ確実に1歩近づくような2番目の定義,のどちらかが呼ばれる`print_multiple_times/2`を定義しました. + We defined `print_multiple_times/2` so that no matter what number is passed as the second argument it either triggers our first definition (known as a "base case") or it triggers our second definition which will ensure that we get exactly 1 step closer to our base case. +リストにある数の合計を求めるときに再帰の力をどう使えるか見てみましょう. + Let's now see how we can use the power of recursion to sum a list of numbers. ```elixir @@ -64,8 +83,12 @@ end Math.sum_list([1, 2, 3], 0) #=> 6 ``` +`sum_list`へ引数としてリスト`[1,2,3]`と初期値`0`を渡して呼び出しています.パターンマッチングのルールと一致するものが見つかるまで,それぞれの句へマッチを試みていきます.この場合だとリスト`[1,2,3]`は`[head|tail]`へマッチし,`head = 1`と`tail = [2,3]`,`accumulator`は`0`へと割り当てられます. + We invoke `sum_list` with a list `[1,2,3]` and the initial value `0` as arguments. We will try each clause until we find one that matches according to the pattern matching rules. In this case, the list `[1,2,3]` matches against `[head|tail]` which assigns `head = 1` and `tail = [2,3]` while `accumulator` is set to `0`. +次にリストの先端(head)とアキュムレーターを足し(`head + accumulator`),リストの残り(tail)を1番目の引数として渡して`sum_list`を再帰的に呼び出します.リストの残りは再び`[head|tail]`へマッチし,リストが空になるまで以下のように続きます: + Then, we add the head of the list to the accumulator `head + accumulator` and call `sum_list` again, recursively, passing the tail of the list as its first argument. The tail will once again match `[head|tail]` until the list is empty, as seen below: ```elixir @@ -75,10 +98,16 @@ sum_list [3], 3 sum_list [], 6 ``` +リストが空になると,最後の句にマッチし最終結果の`6`が返ります. + When the list is empty, it will match the final clause which returns the final result of `6`. +このリストをとって一つの値へ"減らしていく(reducing)"という手法は"reduce"アルゴリズムと呼ばれており,関数型プログラミングの中心をなしています. + The process of taking a list and "reducing" it down to one value is known as a "reduce" algorithm and is central to functional programming. +もしリストの全ての値を2倍にしたければ何をすればよいでしょう? + What if we instead want to double all of the values in our list? ```elixir @@ -95,10 +124,16 @@ end Math.double_each([1, 2, 3]) #=> [2, 4, 6] ``` +リストを再帰的にたどり,全ての要素を2倍にし,新しいリストを返しています.この,リストをとって"写しとる(mapping)"手法は"map"アルゴリズムと呼ばれています. + Here we have used recursion to traverse a list doubling each element and returning a new list. The process of taking a list and "mapping" over it is known as a "map" algorithm. +再帰と末尾呼び出し最適化はElixirの重要な部分で,ループを作るのによく利用されています.しかしElixirでプログラミングしているときにリストの操作に上でやったような再帰を使うことはほとんどないでしょう. + Recursion and tail call optimization are an important part of Elixir and are commonly used to create loops. However, when programming Elixir you will rarely use recursion as above to manipulate lists. +次の章で学ぶ[`Enum`モジュール](/docs/stable/elixir/Enum.html)は既にリストを扱うのに便利な様々なものを提供しています.例えば上の例は次のように書けてしまいます: + The [`Enum` module](/docs/stable/elixir/Enum.html), which we are going to study in the next chapter, already provides many conveniences for working with lists. For instance, the examples above could be written as: ```iex @@ -108,6 +143,8 @@ iex> Enum.map([1, 2, 3], fn(x) -> x * 2 end) [2, 4, 6] ``` +あるいはキャプチャー構文を使えばこのように: + Or, using the capture syntax: ```iex @@ -117,4 +154,6 @@ iex> Enum.map([1, 2, 3], &(&1 * 2)) [2, 4, 6] ``` +それではEnumerableとStreamについてもっと詳しくみていきましょう. + So let's take a deeper look at Enumerables and Streams. From c75bb53828958f61f6c077a5e9c2c4d80edd2fb6 Mon Sep 17 00:00:00 2001 From: niku Date: Thu, 29 May 2014 20:39:41 +0900 Subject: [PATCH 10/15] Translate into japanese(10 Enumerables and Streams) --- getting_started/10.markdown | 46 +++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/getting_started/10.markdown b/getting_started/10.markdown index 805d3a44b..ed95b9c01 100644 --- a/getting_started/10.markdown +++ b/getting_started/10.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 10 Enumerables and Streams +title: 10 enumerableとstream - Enumerables and Streams guide: 10 --- @@ -9,7 +9,9 @@ guide: 10

-## 10.1 Enumerables +## 10.1 enumerable - Enumerables + +Elixirはenumerable(列挙できる)という概念と,一緒に動かせる[`Enum`モジュール](/docs/stable/elixir/Enum.html)を用意しています.私たちは既に2つのenumerableを学びました: リストとマップです. Elixir provides the concept of enumerables and [the `Enum` module](/docs/stable/elixir/Enum.html) to work with them. We have already learned two enumerables: lists and maps. @@ -20,8 +22,12 @@ iex> Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end) [2, 12] ``` +`Enum`モジュールはenumerableなアイテムを変形,並びかえ,グルーピング,フィルタリング,検索するための非常に多様な関数を提供しています.Elixirのコードの中で頻繁に利用するモジュールの一つです. + The `Enum` module provides a huge range of functions to transform, sort, group, filter and retrieve items from enumerables. It is one of the modules developers use frequently in their Elixir code. +Elixirは範囲も提供しています: + Elixir also provides ranges: ```iex @@ -31,11 +37,17 @@ iex> Enum.reduce(1..3, 0, &+/2) 6 ``` +ごらんの通りEnumモジュールは異なるデータ型でも動作するように考えられているので,そのAPIは様々なデータ型で使いやすいものだけになっています.あるデータ型固有の特徴的な操作はその固有のモジュールでやることになるでしょう.例えば,もしリストの特定の場所へ要素を挿入したい場合は,[`List`モジュール](/docs/stable/eliir/List.html)の関数`List.insert_at/3`を使うでしょう.たとえば範囲へ値を挿入するのはちょっと変な感じがしますもんね. + Since the Enum module was designed to work across different data types, its API is limited to functions that are useful across many data types. For specific operations, you may need to reach to modules specific to the data types. For example, if you want to insert an element at a given position in a list, you should use the `List.insert_at/3` function from [the `List` module](/docs/stable/elixir/List.html), as it would make little sense to insert a value into, for example, a range. +様々なデータ型で動作するので,私たちは`Enum`モジュールの関数はポリモーフィックであると言っています.とりわけ`Enum`モジュールにある関数は[`Enumerable`プロトコル](/docs/stable/elixir/Enumerable.html)を実装したどんなデータ型でも動作するようになっています.後ほどプロトコルについて話しましょう,今はstreamと呼ばれるenumerableの一種をみていくことにします. + We say the functions in the `Enum` module are polymorphic because they can work with diverse data types. In particular, the functions in the `Enum` module can work with any data type that implements [the `Enumerable` protocol](/docs/stable/elixir/Enumerable.html). We are going to discuss Protocols in a later chapter, for now we are going to move on to a specific kind of enumerable called streams. -## 10.2 Eager vs Lazy +## 10.2 貪欲 vs 怠惰 - Eager vs Lazy + +`Enum`モジュールの関数は全て貪欲です.たくさんの関数は一つのenumerableをとって一つのリストを返します: All the functions in the `Enum` module are eager. Many functions expect an enumerable and return a list back: @@ -46,6 +58,8 @@ iex> Enum.filter(1..3, odd?) [1, 3] ``` +つまり`Enum`で複数の操作をしたとき,結果が出るまで全ての操作が中間リストを作るということになります: + This means that when performing multiple operations with `Enum`, each operation is going to generate an intermediate list until we reach the result: ```iex @@ -53,8 +67,12 @@ iex> 1..100_000 |> Enum.map(&(&1 * 3)) |> Enum.filter(odd?) |> Enum.sum 7500000000 ``` +上の例は操作をパイプラインでつなげています.まず範囲からはじまり,範囲の全ての要素を3倍します.最初の操作で`100_000`個の要素のリストができます.次にリストの中の全ての奇数を残すと,`50_000`個の要素をもった新しいリストができ,それから全ての要素を足し合わせます. + The example above has a pipeline of operations. We start with a range and then multiply each element in the range by 3. This first operation will now create and return a list with `100_000` items. Then we keep all odd elements from the list, generating a new list, now with `50_000` items, and then we sum all entries. +Elixirではかわりに,遅延操作できる[`Stream`モジュール](/docs/stable/elixir/Stream.html)を用意しています. + As an alternative, Elixir provides [the `Stream` module](/docs/stable/elixir/Stream.html) which supports lazy operations: ```iex @@ -62,12 +80,18 @@ iex> 1..100_000 |> Stream.map(&(&1 * 3)) |> Stream.filter(odd?) |> Enum.sum 7500000000 ``` +中間リストを生成するかわりに,streamは`Enum`モジュールへ値を渡したときだけ実行される一連の処理を作ります.streamは大きかったり*無限かもしれない*集まりを扱うのに便利です. + Instead of generating intermediate lists, streams create a series of computations that are invoked only when we pass it to the `Enum` module. Streams are useful when working with large, *possibly infinite*, collections. -## 10.3 Streams +## 10.3 stream - Streams + +streamはlazyで,composableなenumerableです. Streams are lazy, composable enumerables. +上の例で観たように`1..100_000 |> Stream.map(&(&1 * 3))`は`1..100_000`の範囲に対して`map`を処理する表現であるstreamというデータ型を返すので,lazyです. + They are lazy because, as shown in the example above, `1..100_000 |> Stream.map(&(&1 * 3))` returns a data type, an actual stream, that represents the `map` computation over the range `1..100_000`: ```iex @@ -75,6 +99,8 @@ iex> 1..100_000 |> Stream.map(&(&1 * 3)) #Stream<1..100_000, funs: [#Function<34.16982430/1 in Stream.map/2>]> ``` +さらに,複数のstream処理を通せるため,composableです. + Furthermore, they are composable because we can pipe many stream operations: ```iex @@ -82,6 +108,8 @@ iex> 1..100_000 |> Stream.map(&(&1 * 3)) |> Stream.filter(odd?) #Stream<1..100_000, funs: [...]> ``` +`Stream`モジュールは引数へ全てのenumerableでも受けつけ,結果としてStreamを返します.無限になるかもしれないstreamを作る関数も用意しています.例えば`Stream.cycle/1`は与えられたenumerableを無限に繰り返すstreamを作るのに使われます.永遠に繰り返すことになるので,こういったstreamから`Enum.map/2`のような関数を呼び出すことのないように気をつけてください: + Many functions in the `Stream` module accept any enumerable as argument and return a stream as result. It also provides functions for creating streams, possibly infinite. For example, `Stream.cycle/1` can be used to create a stream that cycles a given enumerable infinitely. Be careful to not call a function like `Enum.map/2` on such streams, as they would cycle forever: ```iex @@ -91,6 +119,8 @@ iex> Enum.take(stream, 10) [1, 2, 3, 1, 2, 3, 1, 2, 3, 1] ``` +一方`Stream.unfold/2`は与えられた初期値から値を生成するのに使われます: + On the other hand, `Stream.unfold/2` can be used to generate values from a given initial value: ```iex @@ -100,6 +130,8 @@ iex> Enum.take(stream, 3) ["h", "e", "ł"] ``` +その他の興味深い関数としてリソースを包むために使える`Stream.resource/3`があります.これはどこか途中で失敗したとしてもenumerationする前には正しく開かれ,終わったら閉じられることを保証します.例えば,私たちはファイルをstreamで扱うことができます: + Another interesting function is `Stream.resource/3` which can be used to wrap around resources, guaranteeing they are opened right before enumeration and closed afterwards, even in case of failures. For example, we can use it to stream a file: ```iex @@ -108,8 +140,14 @@ iex> stream = File.stream!("path/to/file") iex> Enum.take(stream, 10) ``` +上の例はあなたが選んだファイルの最初の10行を取得します.このようにstreamは大きいファイルやネットワークのような遅いリソースを扱うのにとても使いやすいです. + The example above will fetch the first 10 lines of the file you have selected. This means streams can be very useful for handling large files or even slow resources like network resources. +最初は[`Enum`](/docs/stable/elixir/Enum.html)や[`Stream`](/docs/stable/elixir/Stream.html)モジュールの関数や機能たちについて身構えてしまうでしょうが,回数を重ねるにつれだんだんと慣れていくでしょう.特に最初は`Enum`モジュールに集中して,遅いリソースや大きな(もしかしたら無限の)コレクションを扱うために遅延が必要であるものだけ`Stream`にしていくことになるでしょう. + The amount of functions and functionality in [`Enum`](/docs/stable/elixir/Enum.html) and [`Stream`](/docs/stable/elixir/Stream.html) modules can be daunting at first but you will get familiar with them case by case. In particular, focus on the `Enum` module first and only move to `Stream` for the particular scenarios where laziness is required to either deal with slow resources or large, possibly infinite, collections. +次はElixirの中心的な特徴である,並行,並列,分散処理を簡単にわかりやすく簡単に書けるようにしてくれる,プロセスについて見ることにします. + Next we'll look at a feature central to Elixir, Processes, which allows us to write concurrent, parallel and distributed programs in an easy and understandable way. From fe78b55a048a11e689e229d8019750e5642fa0c7 Mon Sep 17 00:00:00 2001 From: niku Date: Fri, 2 May 2014 20:58:01 +0900 Subject: [PATCH 11/15] Translate into japanese(11 Processes) --- getting_started/11.markdown | 74 ++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/getting_started/11.markdown b/getting_started/11.markdown index 27f5dc20d..f494e9245 100644 --- a/getting_started/11.markdown +++ b/getting_started/11.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 11 Processes +title: 11 プロセス - Processes guide: 11 --- @@ -8,13 +8,21 @@ guide: 11
+Elixirでは全てのコードはプロセスの内部で動きます.プロセス同士は独立,並行して動き,メッセージパッシングでやり取りします.プロセスはElixirにおける並行の基本となるばかりではなく,分散や高可用なプログラムの構築にも役立ちます. + In Elixir, all code runs inside processes. Processes are isolated from each other, run concurrent to one another and communicate via message passing. Processes are not only the basis for concurrency in Elixir, but they also provide the means for building distributed and fault-tolerant programs. +ElixirのプロセスをOSのプロセスと混同してはいけません.プロセスは(他の多くのプログラミング言語におけるスレッドとは異なり)メモリとCPUにとって非常に軽量です.ですから,同時に動作する数千のプロセスを保持することは特別珍しいことではありません. + Elixir's processes should not be confused with operating system processes. Processes in Elixir are extremely lightweight in terms of memory and CPU (unlike threads in many other programming languages). Because of this, it is not uncommon to have dozens of thousands of processes running simultaneously. +この章では,私たちは新しいプロセスを生み出す方法,異なるプロセスのあいだでメッセージをうまく送ったり受けとったりする方法といった基本的な構造を学んでいきます. + In this chapter, we will learn about the basic constructs for spawning new processes, as well as sending and receiving messages between different processes. -## 11.1 spawn +## 11.1 spawn(生み出す) - spawn + +新しいプロセスを生み出すための基本的な方法は,自動インポートされている関数`spawn/1`を使うことです: The basic mechanism for spawning new processes is with the auto-imported `spawn/1` function: @@ -23,8 +31,12 @@ iex> spawn fn -> 1 + 2 end #PID<0.43.0> ``` +`spawn/1`は,他のプロセスで実行する関数を受けとります. + `spawn/1` takes a function which it will execute in another process. +`spawn/1`はPID(プロセス識別子)を返すことに注意してください.ここで生み出したプロセスはたぶんすぐに死にます.生み出されたプロセスは与えられた関数を実行し,関数が終わったら終了します: + Notice `spawn/1` returns a PID (process identifier). At this point, the process you spawned is very likely dead. The spawned process will execute the given function and exit after the function is done: ```iex @@ -34,8 +46,12 @@ iex> Process.alive?(pid) false ``` +> メモ: (手元で試すと)恐らくガイドで書いてあるのとは別のプロセス識別子になるでしょう. + > Note: you will likely get different process identifiers than the ones we are getting in this guide. +`self/0`を呼ぶことで今動いているプロセスのPIDを入手することができます: + We can retrieve the PID of the current process by calling `self/0`: ```iex @@ -45,9 +61,13 @@ iex> Process.alive?(self()) true ``` +プロセスは私たちがメッセージを送受信できるようになるとさらに面白い存在になります. + Processes get much more interesting when we are able to send and receive messages. -## 11.2 send and receive +## 11.2 送信と受信 - send and receive + +`send/2`を使ってプロセスへメッセージを送り,`receive/1`を使って受けとることができます: We can send messages to a process with `send/2` and receive them with `receive/1`: @@ -61,8 +81,12 @@ iex> receive do "world" ``` +メッセージがプロセスから送られてくると,メッセージはプロセスのメールボックスへ保存されます.`receive/2`ブロックは与えられたパターンにマッチするいずれかのメッセージを現在のプロセスのメールボックスから探します.`receive/1`は`case/2`のように複数の句を取ることができ,句のガードとしてうまく動作します. + When a message is sent to a process, the message is stored in the process mailbox. The `receive/2` block goes through the current process mailbox searching for a message that matches any of the given patterns. `receive/1` supports many clauses, like `case/2`, as well as guards in the clauses. +もしパターンにマッチするメッセージがメールボックスに無ければ,現在のプロセスはマッチするメッセージがくるまで待ち続けます.タイムアウトを指定することもできます: + If there is no message in the mailbox matching any of the patterns, the current process will wait until a matching message arrives. A timeout can also be specified: ```iex @@ -74,8 +98,12 @@ iex> receive do "nothing after 1s" ``` +既にメッセージがメールボックスにあることを期待しているならタイムアウトを0にすることもできます. + A timeout of 0 can be given when you already expect the message to be in the mailbox. +プロセス同士でメッセージを送りあってみましょう: + Let's put all together and send messages in between processes: ```iex @@ -89,6 +117,8 @@ iex> receive do "Got hello from #PID<0.48.0>" ``` +シェルから行なう場合,`flush/0`が便利かもしれません.メールボックスにある全てのメッセージを表示し,空にします. + While in the shell, you may find the helper `flush/0` quite useful. It flushes and prints all the messages in the mailbox. ```iex @@ -99,7 +129,9 @@ iex> flush() :ok ``` -## 11.3 Links +## 11.3 リンク - Links + +Elixirでspawnするときに一番よく使われているのは`spawn_link/1`を経由するものです.`spawn_link/1`の例を見るまえに,プロセスが失敗したときにどんなことが起こるかを見てみましょう: The most common form of spawning in Elixir is actually via `spawn_link/1`. Before we show an example with `spawn_link/1`, let's try to see what happens when a process fails: @@ -108,6 +140,8 @@ iex> spawn fn -> raise "oops" end #PID<0.58.0> ``` +むむっ……何も起こりません.なぜならプロセス同士は独立しているためです.もし,あるプロセスでの失敗を他のプロセスへ伝播させたければリンクを使うべきです.`spawn_link/1`を使えばできます: + Well... nothing happened. That's because processes are isolated. If we want the failure in one process to propagate to another one, we should link them. This can be done with `spawn_link/1`: ```iex @@ -118,6 +152,8 @@ iex> spawn_link fn -> raise "oops" end :erlang.apply/2 ``` +シェルで失敗した場合,シェルは自動的に失敗を受けとって,読みやすい形で表示してくれます.自分達のコードで実際には何が起きるのかわかりやすいように,`spawn_link/1`をファイルの中で使い,動かしてみます: + When a failure happens in the shell, the shell automatically traps the failure and shows it nicely formatted. In order to understand what would really happen in our code, let's use `spawn_link/1` inside a file and run it: ```iex @@ -129,18 +165,28 @@ receive do end ``` +この場合プロセスが失敗し,リンクしているので親プロセスも落ちます.`Process.link/2`を呼べばリンクを手動で行うこともできます.プロセスがどんな機能を提供しているか知るのに[`Process`モジュール](/docs/stable/elixir/Process.html)を眺めることをおすすめします. + This time the process failed and brought the parent process down as they are linked. Linking can also be done manually by calling `Process.link/2`. We recommend you to take a look at [the `Process` module](/docs/stable/elixir/Process.html) for other functionality provided by processes. +プロセスとリンクは可用性の高いシステムを構築するのに大事な役割を担っています.Elixirのアプリケーションではしばしば,プロセスが死んでしまった際に検知し,同じ場所で新しいプロセスを動かすため,私たちが作るプロセスとスーパーバイザー(監視役)をリンクさせます.これができるのはプロセスがデフォルトでは何も共有しないためです.そしてもしプロセスが独立しているなら,プロセス内での失敗が他のプロセスをクラッシュさせたり状態を壊したりすることは絶対ににありません. + Process and links play an important role when building fault-tolerant systems. In Elixir applications, we often link our processes to supervisors which will detect when a process die and start a new process in its place. This is only possible because processes are isolated and don't share anything by default. And if processes are isolated, there is no way a failure in a process will crash or corrupt the state of another. +Process and links play an important role when building fault-tolerant systems. In Elixir applications we often link our processes to supervisors which will detect when a process die and start a new process in its place. This is only possible because processes don't share anything by default so there is no way the crash of a process can corrupt the state of another process! + +他の言語では例外は受けとったり操作することが求められますが,Elixirではスーパーバイザーがシステムを再起動してくれるであろうため,プロセスは失敗するがままにしておいてかまいません."早く失敗する"はElixirでソフトウェアを書く際の一般的な指針です! + While other languages would require us to catch/handle exceptions, in Elixir we are actually fine with letting process fail because we expect supervisors to properly restart our systems. "Failing fast" is a common philosophy when writing Elixir software! -Before moving to the next chapter, let's see one of the most common use case for creating processes in Elixir. +## 11.4 状態 - State -## 11.4 State +このガイドでまだ状態について話していませんでした.もし状態が必要なアプリケーション,例えばアプリケーションの設定を保持したり,ファイルを解析してメモリに保持するときに,どこに保存しておけばよいのでしょうか? We haven't talked about state so far in this guide. If you are building an application that requires state, for example, to keep your application configuration, or you need to parse a file and keep it in memory, where would you store it? +この質問のもっとも一般的な回答としてはプロセスです.私たちは無限ループする,状態を保持するプロセスを書くことができ,メッセージを送ったり受けたりすることができます.例えば,新しいプロセスでキーバリューストアとして動作する,`kv.exs`というファイル名のモジュールを書いてみましょう: + Processes are the most common answer to this question. We can write processes that loops infinitely, keeping a state, and sending and receiving messages. As an example, let's write a module that starts new processes that work as a key-value store in a file named `kv.exs`: ```elixir @@ -161,8 +207,12 @@ defmodule KV do end ``` +関数`start`は,関数`loop/1`を動かすような新しいプロセスを,最初に空のマップを渡して,単純に産み出していることに注目してください.関数`loop/1`はメッセージを待ち受け,どのメッセージにも適切な動作をします.`:get`メッセージの場合,呼び出し元へメッセージを送り返し,再び`loop/1`を呼び出し,新しいメッセージを待ちます.`:put`メッセージの場合,与えられた`key`と`value`を保存した新しいバージョンのマップで`loop/1`を呼び出します. + Note that the `start` function basically spawns a new process that runs the `loop/1` function, starting with an empty map. The `loop/1` function then waits for messages and perform the appropriate action for each message. In case of a `:get` message, it sends a message back to the caller and calls `loop/1` again, to wait for a new message. While the `:put` message actually makes `loop/1` be invoked with a new version of the map, with the given `key` and `value` stored. +`iex kv.exs`で動かして試してみましょう: + Let's give it a try by running `iex kv.exs`: ```iex @@ -174,6 +224,8 @@ iex> flush nil ``` +最初,マップには何もキーがありません,ですから現在のプロセスへ`:get`メッセージを送って,inboxをフラッシュさせても`nil`が返ります.`:put`メッセージを送って再び試してみましょう: + At first, the process map has no keys, so sending a `:get` message and then flushing the current process inbox returns `nil`. Let's send a `:put` message and try it again: ```iex @@ -185,8 +237,12 @@ iex> flush :world ``` +どうやってプロセスが状態を保持しているか,そしてメッセージを送ることで取得や更新ができることをご覧ください.実際,`pid`を知っているどんなプロセスにも,上のようにしてメッセージを送ることができ,状態を操作することができます. + Notice how the process is keeping a state and we can get and update this state by sending the process messages. In fact, any process that knows the `pid` above will be able to send it messages and manipulate the state. +名前を与えてpidを登録もでき,そうすると名前を知る全て(のプロセス)がメッセージを送ることができます: + It is also possible to register the pid, giving it a name, and allowing everyone that knows the name to send it messages: ```iex @@ -198,6 +254,8 @@ iex> flush :world ``` +Elixirのアプリケーションにおいて,プロセスに状態を持たせ,名前の登録をすることは良くおこなわれています.しかしほとんどの場合,上のように手で実装することはなく,Elixirが提供している抽象物のどれかを使います.例えばElixirは状態を利用する[agents](/docs/stable/elixir/Agent.html)という単純な抽象物を提供しています: + Using process around state and name registering are very common patterns in Elixir applications. However, most of the time, we won't implement those patterns manualy as above, but using one of the many of the abstractions that ships with Elixir. For example, Elixir provides [agents](/docs/stable/elixir/Agent.html) which are simple abstractions around state: ```iex @@ -209,6 +267,10 @@ iex> Agent.get(pid, fn map -> Map.get(map, :hello) end) :world ``` +`Agent.start/2`へは`:name`オプションを渡すことができ,その場合は自動的に登録されます.Elixirは(GenServerと呼ばれている)一般的なサーバー,(GenEventと呼ばれる)一般的なイベント管理と一般的なイベント処理,タスクなど,agentと同じようにプロセスによって実現されているAPIを提供しています.スーパーバイザーの連なり(supervision tree)による,起動から終了までを全てElixirアプリケーションで構築するためのもっと詳しい内容はMixとOTPのガイドのところで行います. + A `:name` option could also be given to `Agent.start/2` and it would be automatically registered. Besides agents, Elixir provides an API for building generic servers (called GenServer), generic event managers and event handlers (called GenEvent), tasks and more, all powered by processes underneath. Those, along with supervision trees, will be explored with more detail in the Mix and OTP guide which will build a complete Elixir application from start to finish. +今はElixirのI/Oの世界への探検に向かいましょう. + For now, let's move on and explore the world of I/O in Elixir. From 09d192a2e97ec867be1569c3fca93396e47ae5d8 Mon Sep 17 00:00:00 2001 From: niku Date: Thu, 8 May 2014 20:00:10 +0900 Subject: [PATCH 12/15] Translate into japanese(12 IO) --- getting_started/12.markdown | 64 +++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/getting_started/12.markdown b/getting_started/12.markdown index d0a16033f..1d14dffac 100644 --- a/getting_started/12.markdown +++ b/getting_started/12.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 12 IO +title: 12 入出力 - IO guide: 12 --- @@ -8,11 +8,17 @@ guide: 12
+この章はElixirの入出力機構,および,[`IO`](/docs/stable/elixr/IO.html),[`File`](/docs/stable/elxir/File.html)あるいは[`Path`](/docs/stable/elixir/Path.html)などの入出力機構へ関連するモジュールについての紹介をします. + This chapter is a quick introduction to input/output mechanisms in Elixir and related modules, like [`IO`](/docs/stable/elixir/IO.html), [`File`](/docs/stable/elixir/File.html) and [`Path`](/docs/stable/elixir/Path.html). +この章の(入出力の)概要はGetting Startedの前の版にもすでにありました.ですが,入出力システムはElixirとそのVMについていくつかの方針とおもしろさへ光を当てるすばらしい機会を用意していることに気がつきました. + We had originally sketched this chapter to come much earlier in the getting started guide. However, we noticed the IO system provides a great opportunity to shed some light on some philosophies and curiosities of Elixir and the VM. -## 12.1 The IO module +## 12.1 入出力モジュール - The IO module + +Elixirの`IO`モジュールは標準入出力(`:stdio`),標準エラー(`:stderr`),ファイル,あるいは他の入出力デバイスを読み書きするための基本となる部分です.モジュールの使い方はこのようになります: The `IO` module in Elixir is the main mechanism for reading and writing to the standard io (`:stdio`), standard error (`:stderr`), files and other IO devices. Usage of the module is pretty straight-forward: @@ -25,6 +31,8 @@ yes or no? yes "yes\n" ``` +デフォルトでは入出力モジュールの関数は標準入力と標準出力を利用します.引数として`:stderr`を渡すことで標準エラーデバイスへ出力することができます: + By default, the functions in the IO module use the standard input and output. We can pass the `:stderr` as argument to write to the standard error device: ```iex @@ -33,7 +41,9 @@ iex> IO.puts :stderr, "hello world" :ok ``` -## 12.2 The File module +## 12.2 ファイルモジュール - The File module + +[`File`](/docs/stable/elixir/File.html)モジュールはファイルを入出力デバイスとして開くことのできる関数を持っています.デフォルトではファイルはバイナリモードで開かれます,必要があれば`IO`モジュールの`IO.binread/2`と`IO.binwrite/2`を使うこともできます: The [`File`](/docs/stable/elixir/File.html) module contains functions that allows us to open files as IO devices. By default, files are opened in binary mode, which requires developers to use the specific `IO.binread/2` and `IO.binwrite/2` functions from the `IO` module: @@ -48,6 +58,8 @@ iex> File.read "hello" {:ok, "world"} ``` +ファイルを`:utf8`エンコーディングで開くこともでき,(訳注:エンコーディングの指定は)`IO`モジュールの他の関数でも使えます. + A file can also be opened with `:utf8` encoding which allows the remaining functions in the `IO` module to be used: ```iex @@ -55,8 +67,12 @@ iex> {:ok, file} = File.open "another", [:write, :utf8] {:ok, #PID<0.48.0>} ``` +一方,ファイルを開いたり,読み書きする関数については,`File`モジュールがファイルシステム上で動く関数をたくさん持っています.例えば`File.rm/1`はファイルを削除するのに使え,`File.mkdir/1`はディレクトリを作り,`File.mkdir_p/1`は必ず親ディレクトリがあるようにディレクトリを(場合によっては複数)作り,`File.cp_r/2`や`File.rm_rf/2`はファイルとディレクトリのコピーと削除を再帰的に行います. + Besides functions for opening, reading and writing files, the `File` module has many functions that work on the file system. Those functions are named after their UNIX equivalents. For example, `File.rm/1` can be used to remove files, `File.mkdir/1` to create directories, `File.mkdir_p/1` creates directories guaranteeing their parents exists and there is even `File.cp_r/2` and `File.rm_rf/2` which copy and remove files and directories recursively. +`File`モジュールの関数には2種類の慣習があることに気づくでしょう,1つは`!`(バンと読みます)つきのもので,もう1つはつかないものです.例えば"hello"というファイルを読むとき,上の例で`!`がつかない方を既に使いましたね.新しい例をいくつか試してみましょう: + You will also notice that functions in the `File` module have two variants, one with `!` (bang) in its name and others without. For example, when we read the "hello" file above, we have used the one without `!`. Let's try some new examples: ```iex @@ -70,12 +86,16 @@ iex> File.read! "unknown" ** (File.Error) could not read file unknown: no such file or directory ``` +ファイルが無い場合,`!`がついたバージョンではエラーが発生していますね.つまり`!`のつかないバージョンはパターンマッチングを利用して異なる形式の結果を取り扱おうとするときに選びます.しかし,もしファイルがそこにあること期待しているなら,バンつきの方が例外のエラーメッセージがわかりやすいので便利です.つまり絶対にこう書かないでください: + Notice that when the file does not exist, the version with `!` raises an error. That said, the version without `!` is preferred when you want to handle different outcomes with pattern matching. However, if you expect the file to be there, the bang variation is more useful as it raises a meaningful error message. That said, never write: ```elixir {:ok, body} = File.read(file) ``` +そのかわりにこう書いてください: + Instead write: ```elixir @@ -85,13 +105,17 @@ case File.read(file) do end ``` +あるいはこうです + or ```elixir File.read!(file) ``` -## 12.3 The Path module +## 12.3 パスモジュール - The Path module + +ファイルモジュールの関数の多くは引数としてパスを期待しています.たいていの場合,これらのパスはバイナリであり[`Path`](/docs/stable/elixir/Path.html)モジュールで操作できます: The majority of the functions in the File module expects paths as arguments. Most commonly, those paths will be binaries and they can be manipulated with the [`Path`](/docs/stable/elixir/Path.html) module: @@ -102,9 +126,13 @@ iex> Path.expand("~/hello") "/Users/jose/hello" ``` +ここまでで,ファイルシステムを使った入出力の主なモジュールについてやりました.次に,なじみの少ない,進んだ入出力の話題について話していきましょう.このセクションはElixirのコードを書く必要がありません,ですから気軽に飛ばしてしまってもよいです,ただ,VMで入出力システムがどのように実装されているかの概要や,その他VMのおもしろい点についてお伝えします. + With this we have covered the main modules for doing IO and interacting with the file system. Next we will discuss some curiosities and advanced topics regarding IO. Those sections are not necessary to write Elixir code, so feel free to skip them, but they do provide an overview of how the IO system is implemented in the VM and other curiosities. -## 12.4 Processes and group leaders +## 12.4 プロセスとグループリーダー - Processes and group leaders + +`File.open/2`がPIDを含んだタプルを返すことを覚えているかもしれません: You may have noticed that `File.open/2` returned a tuple containing a PID: @@ -113,6 +141,8 @@ iex> {:ok, file} = File.open "hello", [:write] {:ok, #PID<0.47.0>} ``` +これは入出力モジュールがプロセスの中で実際に動いているためです.`IO.write(pid, binary)`と書くと,入出力モジュールはメッセージをやりたい操作と共にプロセスへ送ります.自身のプロセスを使ってみたときに何が起こるかみてみましょう: + That's because the IO module actually works with processes. When you say `IO.write(pid, binary)`, the IO module will send a message to the process with the desired operation. Let's see what happens if we use our own process: ```iex @@ -125,8 +155,12 @@ iex> IO.write(pid, "hello") ** (ErlangError) erlang error: :terminated ``` +`IO.write/2`のあと,入出力モジュールへ表示したい内容が送られているのがわかります.次に,入出力モジュールが何か結果を期待した時点で失敗しています.なぜなら(入出力デバイスを)供給していないためです. + After `IO.write/2`, we can see the request sent by the IO module printed, which then fails since the IO module expected some kind of result, which we did not supply. +[`StringIO`](/docs/stable/elixir/StringIO.html)モジュールは文字列で入出力デバイスのメッセージを実装したものを提供します: + The [`StringIO`](/docs/stable/elixir/StringIO.html) module provides an implementation of the IO device messages on top of a string: ```iex @@ -136,8 +170,12 @@ iex> IO.read(pid, 2) "he" ``` +入出力デバイスとプロセスをモデル化することで,Erlang VMは同じネットワークの異なるノード間でファイルプロセスを交換し,どちらのノードであってもファイルを読み書きできます.全ての入出力デバイスで,どのプロセスにも1つだけグループリーダーと呼ばれる特別なものがあります. + By modelling IO devices with processes, the Erlang VM allows different nodes in the same network to exchange file processes to read/write files in between nodes. Of all IO devices, there is one that is special to each process, called group leader. +`:stdio`と書いた場合,実際には`:stdio`と書いたメッセージをグループリーダーへ送っています: + When you write to `:stdio`, you are actually sending a message to the group leader, which writes to `:stdio`: ```iex @@ -149,12 +187,18 @@ hello :ok ``` +グループリーダーはプロセス毎に設定でき,異なる状況で利用されます.例えばリモート端末でコードを実行する際,リモートノードで表示されたメッセージはリダイレクトされ,リクエストするきっかけになった端末で表示されることを保証します. + The group leader can be configured per process and is used in different situations, for example, when executing code in a remote terminal, it guarantees messages printed in the remote node are redirected and printed in the terminal that triggered the request. -## 12.5 `iodata` and `chardata` +## 12.5 `iodata`と`chardata` - `iodata` and `chardata` + +上でみた全ての例ではファイルへの書き込みにバイナリ/文字列を利用していました.この章のタイトルは"Binaries, strings and char lists"です,以前に,文字列が単なるバイトである一方文字リストはコードポイントのリストであると言いました. In all examples above, we have used binaries/strings when writing to files. In the chapter "Binaries, strings and char lists", we mentioned how strings are simply bytes while char lists are lists with code points. +`IO`と`File`の関数は引数としてリストも取れます.それだけではなく,数値とバイナリが混在したリストのリストも取れます: + The functions in `IO` and `File` also allow lists to be given as arguments. Not only that, they also allow a mixed list of lists, integers and binaries to be given: ```iex @@ -166,10 +210,18 @@ hello world :ok ``` +しかし,これには少し気をつけないといけません.リストは,IOデバイスのエンコーディングの依存を利用して,バイトのかたまり,あるいは文字のかたまりで表現されます.もしファイルがエンコーディングなしで開かれたら,ファイルはrawモードを期待しており,`IO`モジュールの関数は必ず`bin*`ではじまるものが使われます.それらの関数は引数として`iodata`を期待しています,つまりバイト及びバイナリからなるリストが渡されることを期待しているということです. + However, this requires some attention. A list may represent either a bunch of bytes or a bunch of characters and which one to use depends on the encoding of the IO device. If the file is opened without encoding, the file is expected to be in raw mode, and the functions in the `IO` module starting with `bin*` must be used. Those functions expect an `iodata` as argument, i.e. it expects a list of integers representing bytes and binaries to be given. +一方で`:stdio`と`:utf8`のエンコーディングを指定して開いたファイルは`IO`モジュールの残り(訳注`bin*`ではじまらない?)関数で動き,引数として`char_data`を期待します,つまり文字と文字列からなるリストが渡されることを期待しているということです. + On the other hand, `:stdio` and files opened with `:utf8` encoding work with the remaining functions in the `IO` module and those expect a `char_data` as argument, i.e. they expect a list of characters or strings to be given. +とはいえこれはちょっとした違いにすぎず.リストをそれらの関数へ渡そうと意図している場合にだけ詳しく検討すればよいです.バイナリは既にバイト表現されているので,常にrawで扱うことができます. + Although this is a subtle difference, you only need to worry about those details if you intend to pass lists to those functions. Binaries are already represented by the underlying bytes and as such their representation is always raw. +これで入出力デバイスと入出力に関連した機能をざっと見終わりました.[`IO`](/docs/stable/elixir/IO.html),[`File`](/docs/stable/elixir/File.html),[`Path`](/docs/stable/elixir/Path.html)と[`StringIO`](/docs/stable/elixir/StringIO.html)というElixirのモジュールについてや,どのようにVMが入出力の機構をうまく使うか,どのように入出力の操作に(charとioの)データを利用するかについて学びました. + This finishes our tour on IO devices and IO related functionality. We have learned about four Elixir modules, [`IO`](/docs/stable/elixir/IO.html), [`File`](/docs/stable/elixir/File.html), [`Path`](/docs/stable/elixir/Path.html) and [`StringIO`](/docs/stable/elixir/StringIO.html), as well as how the VM uses processes for the underlying IO mechanisms and how to use (char and io) data for IO operations. From dac661078d6cd42c312b206d04a94654c44bf7a6 Mon Sep 17 00:00:00 2001 From: niku Date: Fri, 30 May 2014 00:49:44 +0900 Subject: [PATCH 13/15] Translate into japanese(13 alias, require and import) --- getting_started/13.markdown | 70 +++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/getting_started/13.markdown b/getting_started/13.markdown index 7654fbbcd..5b7f6b57a 100644 --- a/getting_started/13.markdown +++ b/getting_started/13.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 13 alias, require and import +title: 13 alias,requireとimpot - alias, require and import guide: 13 --- @@ -8,9 +8,13 @@ guide: 13
+ソフトウェアの再利用を行いやすくするために,Elixirは3つのディレクティブを用意しています.これから見ていくように,*レキシカルスコープ*を持っているのでディレクティブと呼ばれています. + In order to facilitate software reuse, Elixir provides three directives. As we are going to see below, they are called directives because they have **lexical scope**. -## 13.1 alias +## 13.1 alias - alias + +`alias`によって,与えられたモジュールの名前へ別名をつけることができます.`Math`モジュールが数学に特化した操作のため,特別なリストの実装を使うことを想像してみてください: `alias` allows you to set up aliases for any given module name. Imagine our `Math` module uses a special list implementation for doing math specific operations: @@ -20,6 +24,8 @@ defmodule Math do end ``` +ここから,どんな`List`の参照でも自動的に`Math.List`へと展開されます.オリジナルの`List`へアクセスしたい場合,`Elixir`からモジュールへとアクセスできます. + From now on, any reference to `List` will automatically expand to `Math.List`. In case one wants to access the original `List`, it can be done by accessing the module via `Elixir`: ```elixir @@ -28,20 +34,28 @@ Elixir.List.flatten #=> uses List.flatten Elixir.Math.List.flatten #=> uses Math.List.flatten ``` +> メモ: Elixirの中で定義されている全てのモジュールはElixir名前空間の中に定義されています.しかし,利便性のため,参照するときには"Elixir."を省略することができます. + > Note: All modules defined in Elixir are defined inside a main Elixir namespace. However, for convenience, you can omit "Elixir." when referencing them. +Aliasはショートカットを定義するのに良く使われます.実際,`as`オプションをつけないで`alias`を呼ぶと,モジュール名の最後の部分を自動的に設定します.例えば: + Aliases are frequently used to define shortcuts. In fact, calling `alias` without an `as` option sets the alias automatically to the last part of the module name, for example: ```elixir alias Math.List ``` +は以下と同じです: + Is the same as: ```elixir alias Math.List, as: List ``` +`alias`は**lexically scoped**であることに注意してください,特定の関数の中で別名をセットすることもできます: + Note that `alias` is **lexically scoped**, which allows you to set aliases inside specific functions: ```elixir @@ -57,12 +71,18 @@ defmodule Math do end ``` +上の例のように,`alias`を関数`plus/2`の中で呼び出しても,別名は関数`plus/2`の内部でのみ有効で,`minus/2`へは全く影響しません. + In the example above, since we are invoking `alias` inside the function `plus/2`, the alias will just be valid inside the function `plus/2`. `minus/2` won't be affected at all. -## 13.2 require +## 13.2 require - require + +Elixirはメタプログラミング(コードを生成するコードを書く)のためのメカニズムとしてマクロを用意しています. Elixir provides macros as a mechanism for meta-programming (writing code that generates code). +マクロとはコンパイル時に実行して展開されるコード片のことです.つまり,マクロを使うために,コンパイル時にそのモジュールと実装が用意されている保証が必要になります.`require`ディレクティブを使うとそのようにできます: + Macros are chunks of code that are executed and expanded at compilation time. This means, in order to use a macro, we need to guarantee its module and implementation are available during compilation. This is done with the `require` directive: ```iex @@ -74,11 +94,17 @@ iex> Integer.odd?(3) true ``` +Elixirでは`Integer.odd?/1`はマクロとして定義されているのでガードとして利用できます.つまり`Integer.odd?/1`を実行するためには,まず`Integer`モジュールが必要です. + In Elixir, `Integer.odd?/1` is defined as a macro so it can be used as guards. This means that, in order to invoke `Integer.odd?/1`, we need to first require the `Integer` module. +一般的に,そのモジュールにあるマクロを使おうとする場合以外では,利用前にモジュールが必要とされることはありません,ロードされていないマクロを呼び出そうとした場合はエラーになります.`alias`ディレクティブと同じように,`require`もレキシカルスコープであることに着目してください.マクロについては後の章でまた詳しく話します. + In general a module does not need to be required before usage, except if we want to use the macros available in that module. An attempt to call a macro that was not loaded will raise an error. Note that like the `alias` directive, `require` is also lexically scoped. We will talk more about macros in a later chapter. -## 13.3 import +## 13.3 import - import + +他のモジュールの関数かマクロへ修飾名をつけず簡単にアクセスしたいときに`import`を使います.例えば`List`の`duplicate`関数を何回も使いたい場合,単にインポートできます: We use `import` whenever we want to easily access functions or macros from other modules without using the qualified name. For instance, if we want to use the `duplicate` function from `List` several times, we can simply import it: @@ -89,20 +115,28 @@ iex> duplicate :ok, 3 [:ok, :ok, :ok] ``` +このケースでは,`List`から関数`duplicate`(引数が2のもの)だけをインポートしています.`only:`は省略可能ですが,つけることが推奨されています.`except`もオプションとして与えることができます. + In this case, we are importing only the function `duplicate` (with arity 2) from `List`. Although `only:` is optional, its usage is recommended. `except` could also be given as an option. +`import`では`:only`へ`:macros`と`:functions`を渡すこともできます.例えば全てのマクロをインポートしたい場合はこのように書けます: + `import` also supports `:macros` and `:functions` to be given to `:only`. For example, to import all macros, one could write: ```elixir import Integer, only: :macros ``` +あるいは全ての関数をインポートしてい場合はこのように書けます: + Or to import all functions, you could write: ```elixir import Integer, only: :functions ``` +`import`もまた**lexically scoped**であることに注意してください,これは特定の関数の中で特定のマクロをインポートできることを意味しています. + Note that `import` is also **lexically scoped**, this means we can import specific macros inside specific functions: ```elixir @@ -114,14 +148,22 @@ defmodule Math do end ``` +上の例ではインポートされた`List.duplicate/2`は特定の関数内からしか見えません.`duplicate/2`はそのモジュールの他のどの関数からも(もちろん他のモジュールからも)使えません. + In the example above, the imported `List.duplicate/2` is only visible within that specific function. `duplicate/2` won't be available in any other function in that module (or any other module for that matter). +モジュールをimportすると自動的にrequireすることに注意してください. + Note that importing a module automatically requires it. -## 13.4 Aliases +## 13.4 Alias - Aliases + +ここでもしかしたらElixirのエイリアスとは実際には何で,どのように表現されているのか?ということが気になってきたかもしれません. At this point, you may be wondering, what exactly an Elixir alias is and how it is represented? +Elixirのエイリアスは(`String`,`Keyword`などのような)大文字始まりの識別子でコンパイル時にatomへと変換されます.例えば`String`エイリアスはデフォルトではatom`:"Elixir.String"`へと変換されます: + An alias in Elixir is a capitalized identifier (like `String`, `Keyword`, etc) which is converted to an atom during compilation. For instance, the `String` alias translates by default to the atom `:"Elixir.String"`: ```iex @@ -133,8 +175,12 @@ iex> :"Elixir.String" String ``` +`alias/2`ディレクティブを使うことで,単にエイリアスを何へと変換するかだけを変えています. + By using the `alias/2` directive, we are simply changing what an alias translates to. +詳しく書くと,Erlang VMの中では(つまりElixirでも)モジュールがatomで表現されているのでエイリアスがうまく動きます.例えばErlangのモジュールを使うときのメカニズムはこうです: + Aliases work as described because in the Erlang VM (and consequently Elixir), modules are represented by atoms. For example, that's the mechanism we use to call Erlang modules: ```iex @@ -142,6 +188,8 @@ iex> :lists.flatten([1,[2],3]) [1, 2, 3] ``` +これがモジュールの内部で与えられた関数を動的に呼び出すことができるメカニズムです: + This is also the mechanism that allows us to dynamically call a given function in a module: ```iex @@ -151,9 +199,13 @@ iex> mod.flatten([1,[2],3]) [1,2,3] ``` +言いかえると,`:lists`というアトムにある関数`flatten`を単に呼び出しているだけです. + In other words, we are simply calling the function `flatten` on the atom `:lists`. -## 13.5 Nesting +## 13.5 ネスト - Nesting + +ここでエイリアスについて話してきました,Elixirでのネストがどのように動作するかについても話しましょう.以下の例で考えてみます: Now that we have talked about aliases, we can talk about nesting and how it works in Elixir. Consider the following example: @@ -164,8 +216,12 @@ defmodule Foo do end ``` +この例は`Foo`と`Foo.Bar`という2つのモジュールを定義しています. 後者,`Foo`の中の`Bar`は(`Foo`と)同じレキシカルスコープの中にいます.もし開発者が後で`Bar`を他のファイルへと移動したら,参照するためには,フルネーム(`Foo.Bar`)か上で話していたような`alias`デイレクティブを使ってセットすることが必要になります. + The example above will define two modules `Foo` and `Foo.Bar`. The second can be accessed as `Bar` inside `Foo` as long as they are in the same lexical scope. If later the developer decides to move `Bar` to another file, it will need to be referenced by its full name (`Foo.Bar`) or an alias needs to be set using the `alias` directive discussed above. +言いかえると上のコードは以下と同じです: + In other words, the code above is exactly the same as: ```elixir @@ -176,4 +232,6 @@ defmodule Elixir.Foo do end ``` +後の章で見るように,エイリアスはマクロにおいてのとても重要な役割,健全性の保証を担います.Elixirのモジュールについてはほとんど見て回りました.最後にモジュールの属性について見ていきましょう. + As we will see in later chapters, aliases also play a crucial role in macros, to guarantee they are hygienic. With this we are almost finishing our tour about Elixir modules, the last topic to cover is module attributes. From 7c45faf8dd138da395520c96bec97cd165c3f668 Mon Sep 17 00:00:00 2001 From: niku Date: Thu, 12 Jun 2014 22:05:01 +0900 Subject: [PATCH 14/15] Translate into japanese(14 Module attributes) --- getting_started/14.markdown | 70 ++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/getting_started/14.markdown b/getting_started/14.markdown index 7095682a7..eb47aee40 100644 --- a/getting_started/14.markdown +++ b/getting_started/14.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 14 Module attributes +title: 14 モジュールのアトリビュート - Module attributes guide: 14 --- @@ -8,15 +8,25 @@ guide: 14
+モジュールのアトリビュートには3つの目的があります: + Module attributes in Elixir serve three purposes: +1. 注釈をモジュールへつけます.ユーザーやVMが利用できるような情報のことが多いです +2. 定数として利用します +3. コンパイルの際にモジュールの一時的な保管場所として利用します + 1. They serve to annotate the module, often with information to be used by the user or the VM. 2. They work as constants. 3. They work as a temporary module storage to be used during compilation. +それぞれの場合を一つずつみていきましょう. + Let's check each case, one by one. -## 14.1 As annotations +## 14.1 注釈として - As annotations + +ElixirはモジュールアトリビュートのコンセプトをErlangから持ってきています.例えば: Elixir brings the concept of module attributes from Erlang. For example: @@ -26,15 +36,26 @@ defmodule MyServer do end ``` +上の例では,モジュールのバージョンアトリビュートを明示的に設定しています.`@vsn`はモジュールがアップデートされたかをErlangVMでのコード再読み込みの仕組みでチェックするのに使っています.もしバージョンを指定していなければ,モジュール関数のMD5チェックサムがバージョンへセットされます. + In the example above, we are explicitly setting the version attribute for that module. `@vsn` is used by the code reloading mechanism in the Erlang VM to check if a module has been updated or not. If no version is specified, the version is set to the MD5 checksum of the module functions. +エリクサーには予約済のアトリビュートが少しだけあります.(訳注:種類は)少ししかありませんが頻繁に使われています: + Elixir has a handful of reserved attributes. Here are just a few of them, the most commonly used ones: +* `@moduledoc` - このモジュールのドキュメントを提供します. +* `@doc` - この印の次にある関数やマクロのドキュメントを提供します. +* `@behaviour` - (つづりがイギリス式であることに注意してください)ユーザーが定義した振舞いなのか,OTPが定義した振舞いなのか区別します. +* `@before_compile` - モジュールがコンパイルされる前に実行されるフックを提供します.コンパイル直前にモジュールへ関数を注入することができるようになります. + * `@moduledoc` - provides documentation for the current module. * `@doc` - provides documentation for the function or macro that follows the attribute. * `@behaviour` - (notice the British spelling) used for specifying an OTP or user-defined behaviour. * `@before_compile` - provides a hook that will be invoked before the module is compiled. This makes it possible to inject functions inside the module exactly before compilation. +`@moduledoc`と`@doc`は最も良く使われているアトリビュートで,あなたにも沢山使ってもらえることを願っています.Elixirではドキュメントを大事にしており,ドキュメントへアクセスするための関数もたくさん提供しています: + `@moduledoc` and `@doc` are by far the most used attributes, and we expect you to use them a lot. Elixir treats documentation as first-class and provides many functions to access documentation: ```iex @@ -59,6 +80,8 @@ Returns the version ``` +Elixirでは読みやすいドキュメントを書くためヒアドキュメントでマークダウンを使うようにしています.ヒアドキュメントとは,最初と最後を3つの引用符でくくり,くくった中のテキストのフォーマットを崩さない,複数行の文字列のことです: + Elixir promotes the use of markdown with heredocs to write readable documentation. Heredocs are multiline strings, they start and end with triple quotes, keeping the formatting of the inner text: ```elixir @@ -76,19 +99,33 @@ defmodule Math do end ``` +[ExDoc](https://github.com/elixir-lang/ex_doc)と呼ばれているドキュメントからHTMLページを生成するためのツールも提供しています. + We also provide a tool called [ExDoc](https://github.com/elixir-lang/ex_doc) which is used to generate HTML pages from the documentation. +[Module](/docs/stable/elixir/Module.html)でサポートしているアトリビュートの一覧を見ることができます.Elixirでは[typespecs](/docs/stable/elixir/Kernel.Typespec.html)を定義するのにも以下のようなアトリビュートを使っています: + You can take a look at the docs for [Module](/docs/stable/elixir/Module.html) for a complete list of supported attributes. Elixir also uses attributes to define [typespecs](/docs/stable/elixir/Kernel.Typespec.html), via: +* `@spec` - 関数の仕様を提供します. +* `@callback` - behaviorのコールバック仕様を提供します. +* `@type` - `@spec`の中で型を定義します. +* `@typep` - `@spec`の中でプライベートな型を定義します. +* `@opaque` - `@spec`の中で未確定な型を定義します. + * `@spec` - provides a specification for a function. * `@callback` - provides a specification for the behavior callback. * `@type` - defines a type to be used in `@spec`. * `@typep` - defines a private type to be used in `@spec`. * `@opaque` - defines an opaque type to be used in `@spec`. +このセクションでは組み込み済のアトリビュートについて触れました.しかしそれだけではなく,アトリビュートは開発者に利用されたり,カスタムした振舞いをサポートするためライブラリで拡張されたりもします. + This section covers built-in attributes. However, attributes can also be used by developers or extended by libraries to support custom behaviour. -## 14.2 As constants +## 14.2 定数として - As constants + +Elixir開発者はしばしばモジュールのアトリビュートを定数として使います: Elixir developers will often use module attributes to be used as constants: @@ -99,8 +136,12 @@ defmodule MyServer do end ``` +> メモ: Erlangとちがい,ユーザーが定義したアトリビュートはデフォルトではモジュールに保存されません.値はコンパイル時にのみ存在します.開発者は[`Module.register_attribute/3`](/docs/stable/elixir/Module.html#register_attribute/3)を呼び出すことにより,Erlangと似たような属性の振舞を設定をすることができます. + > Note: Unlike Erlang, user defined attributes are not stored in the module by default. The value exists only during compilation time. A developer can configure an attribute to behave closer to Erlang by calling [`Module.register_attribute/3`](/docs/stable/elixir/Module.html#register_attribute/3). +定義されていないアトリビュートへアクセスしてみるとワーニングが表示されるはずです: + Trying to access an attribute that was not defined will print a warning: ```elixir @@ -110,6 +151,8 @@ end warning: undefined module attribute @unknown, please remove access to @unknown or explicitly set it to nil before access ``` +最後に,アトリビュートは関数の中でも読めます: + Finally, attributes can also be read inside functions: ```elixir @@ -124,12 +167,18 @@ MyServer.first_data #=> 14 MyServer.second_data #=> 13 ``` +関数の内部でアリビュートを読むときには現在のスナップショットの値を取ることに注意してください.言いかえると,値は実際に動かすときではなく,コンパイルするときに読み込まれます.これから見るように,アトリビュートによる貯蔵はモジュールをコンパイルするときに便利です. + Notice that reading an attribute inside a function takes a snapshot of its current value. In other words, the value is read at compilation time and not at runtime. As we are going to see, this makes attributes useful to be used as storage during module compilation. -## 14.3 As temporary storage +## 14.3 一時的な貯蔵 - As temporary storage + +Elixir organizationのプロジェクトの一つが[`Plug`プロジェクト](https://github.com/elixir-lang/plug)で,Elixirでwebライブラリやフレームワークを構築するための共通の基盤になることを意図しています. One of the projects in the Elixir organization is [the `Plug` project](https://github.com/elixir-lang/plug), which is meant to be a common foundation for building web libraries and frameworks in Elixir. +Plugライブラリではウェブサーバーの中で自身のプラグを定義できます. + The Plug library also allows developers to define their own plugs which can be run in a web server: ```elixir @@ -152,10 +201,17 @@ IO.puts "Running MyPlug with Cowboy on http://localhost:4000" Plug.Adapters.Cowboy.http MyPlug, [] ``` +上の例ではウェブリクエストが来たときに呼ばれる関数へと繋げるために`plug/1`マクロを使いました.内部的には,`plug/1`を呼ぶたび,Plugライブラリは与えられた引数を`@plugs`属性の中に貯蔵します.モジュールがコンパイルされる直前に,Plugはあらかじめ定義されているhttpリクエストを取り扱うメソッド(`call/2`)をコールバックします.そのメソッドは`@plugs`の中の全てのplugを順番に実行します. + In the example above, we have used the `plug/1` macro to connect functions that will be invoked when there is a web request. Internally, every time you call `plug/1`, the Plug library stores the given argument in a `@plugs` attribute. Just before the module is compiled, Plug runs a callback that defines a method (`call/2`) which handles http requests. This method will run all plugs inside `@plugs` in order. + +このコードの裏側を理解するためには,マクロが必要です,そこでこのパターンはメタプログラミングガイドで再び眺めることにします.しかしここでは開発者がDSLを作るためにモジュールアトリビュートをストレージとしてどう使ったらよいか明確にすることへ焦点をあてます. + In order to understand the underlying code, we'd need macros, so we will revisit this pattern in the meta-programming guide. However the focus here is exactly on how using module attributes as storage allow developers to create DSLs. +モジュールアトリビュートをアノテーションとストレージに利用している別の例がExUnitにあります: + Another example comes from the ExUnit framework which uses module attributes as annotation and storage: ```elixir @@ -169,8 +225,14 @@ defmodule MyTest do end ``` +ExUnitのタグはテストに注釈を付けるのに使われています.タグはテストをフィルターするのに使われています.例えば遅くて他のサービスに依存しているような外部のテストを自分のマシンで行うことを避けられます,そしてビルドシステムでは依然として有効にしておくことができます. + Tags in ExUnit are used to annotate tests. Tags can be later used to filter tests. For example, you can avoid running external tests on your machine because they are slow and dependent on other services, while they can still be enabled in your build system. +Elixirがどうやってメタプログラミングをサポートしているか,そしてモジュールアトリビュートがどうやってその重要な役割を担っているか,このセクションで多少でもわかるといいなと考えています. + We hope this section shines some light on how Elixir supports meta-programming and how module attributes play an important role when doing so. +次の章では,例外処理やsigil,内包表記などをやる前に,構造やプロトコルについて調べていくことにします. + In the next chapters we'll explore structs and protocols before moving to exception handling and other constructs like sigils and comprehensions. From 9ae4ccd4af39e935bd30290e77c1b1da350ca28c Mon Sep 17 00:00:00 2001 From: niku Date: Fri, 13 Jun 2014 20:45:11 +0900 Subject: [PATCH 15/15] Translate into japanese(15 Structs) --- getting_started/15.markdown | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/getting_started/15.markdown b/getting_started/15.markdown index e931afa2b..b60012908 100644 --- a/getting_started/15.markdown +++ b/getting_started/15.markdown @@ -1,6 +1,6 @@ --- layout: getting_started -title: 15 Structs +title: 15 構造体 - Structs guide: 15 --- @@ -8,6 +8,8 @@ guide: 15
+以前の章でマップについて学びました: + In early chapters, we have learned about maps: ```iex @@ -19,8 +21,12 @@ iex> %{map | a: 3} %{a: 3, b: 2} ``` +構造体は,初期値,コンパイル時の保証および多態をElixirへもたらす,マップを利用した拡張です. + Structs are extensions on top of maps that bring default values, compile-time guarantees and polymorphism into Elixir. +構造体を定義するには,モジュールの中で単に`defstruct/1`を呼びます: + To define a struct, we just need to call `defstruct/1` inside a module: ```iex @@ -31,6 +37,8 @@ iex> defmodule User do <<70, 79, 82, ...>>, {:__struct__, 0}} ``` +すると`%User{}`構文を使って構造体の"インスタンス"が作れるようになります: + We can now create "instances" of this struct by using the `%User{}` syntax: ```iex @@ -42,6 +50,8 @@ iex> is_map(%User{}) true ``` +構造体は,用意しているフィールドが存在することをコンパイル時に保証します. + Structs give compile-time guarantees that the provided fields exist in the struct: ```iex @@ -49,6 +59,8 @@ iex> %User{oops: :field} ** (CompileError) iex:3: unknown key :oops for struct User ``` +マップについて話したとき,既にあるマップのフィールドに対してアクセスやアップデートをできることを示しました.同じことを構造体にもやってみましょう: + When discussing maps, we demonstrated how we can access and update existing fields of a map. The same applies to structs: ```iex @@ -62,8 +74,12 @@ iex> %{eric | oops: :field} ** (ArgumentError) argument error ``` +アップデートの構文を使うと,VMはマップ/構造体へ新しいキーが何も追加されないことを認識し,マップがメモリ内で構造を共有できるようにします.上の例だと,`jose`は`eric`はどちらも同じキーを共有しています. + By using the update syntax, the VM is aware no new keys will be added to the map/struct, allowing the maps to share their structure in memory. In the example above, both `jose` and `eric` share the same key structure in memory. +構造体はパターンマッチングでもよく用いられ,構造体の型が同じであることを保証します: + Structs can also be used in pattern matching and they guarantee the structs are of the same type: ```iex @@ -75,6 +91,8 @@ iex> %User{} = %{} ** (MatchError) no match of right hand side value: %{} ``` +マッチングが動作するのは構造体がマップの中に`__struct__`というフィールドを保存しているからです: + Matching works because structs store a field named `__struct__` inside the map: ```iex @@ -82,6 +100,8 @@ iex> jose.__struct__ User ``` +全体として,構造体は単にデフォルトのフィールドがあるだけの剥き出しのマップです.剥き出しのマップと言ったところに注目してください.マップは構造体のために何のプロトコルも実装していません.例えば構造体を列挙するようなアクセスはできません: + Overall, a struct is just a bare map with default fields. Notice we say it is a bare map because none of the protocols implemented for maps are available for structs. For example, you can't enumerate nor access a struct: ```iex @@ -91,6 +111,8 @@ iex> user[:name] ** (Protocol.UndefinedError) protocol Access not implemented for %User{age: 27, name: "jose"} ``` +構造体ディクショナリでもないので,`Dict`モジュールからも使えません: + A struct also is not a dictionary and therefore can't be used with the `Dict` module: ```iex @@ -98,4 +120,6 @@ iex> Dict.get(%User{}, :name) ** (ArgumentError) unsupported dict: %User{name: "jose", age: 27} ``` +次の章でどうやって構造体がプロトコルを使ってやりとりするか見ていきます. + We will cover how structs interacts with protocols in the next chapter.