はじめに
Elixirを楽しんでいますか
Nervesを楽しんでいますか
マクロの話をします。
Nerves on Raspberry Pi 2の話です。
令和3年なのに、Raspberry Pi 2です。
まだまだ現役バリバリ、イゴいています1
作品群
毎月イベントを開催してくださった、マイクロソフトさん、Qiitaさんに感謝です。
マクロ
Macrosを使っています。
Macrosを使って量産しています
『プログラミングElixir(第2版) -- オーム社』の第22章を読んでください。
先述の作品群のポイントとなるソースコードをご披露しておきます。
共通部分
各「【毎日自動更新】」記事作成のための共通部分です。
defmodule Qiita.Azure do
defmacro __using__(opts) do
item_id = Keyword.get(opts, :item_id)
title = Keyword.get(opts, :title)
event_title = Keyword.get(opts, :event_title)
event_url = Keyword.get(opts, :event_url)
description = Keyword.get(opts, :description)
start = Keyword.get(opts, :start)
ending = Keyword.get(opts, :ending)
quote do
def run do
Qiita.Api.patch_item(
markdown(),
false,
[
%{"name" => "Elixir"},
%{"name" => "QiitaAzure"},
%{"name" => "Azure"},
%{"name" => "Nerves"}
],
unquote(title),
unquote(item_id)
)
end
def items do
start = DateTime.new(unquote(start), ~T[15:00:00.000], "Etc/UTC") |> elem(1)
ending = DateTime.new(unquote(ending), ~T[15:00:00.000], "Etc/UTC") |> elem(1)
Qiita.Api.items("tag:QiitaAzure tag:Azure created:>#{unquote(start) |> Date.to_string()}")
|> Enum.filter(fn %{"created_at" => created_at} ->
Timex.between?(created_at, start, ending, inclusive: :start)
end)
|> Enum.sort_by(fn %{"likes_count" => likes_count} -> likes_count end, :desc)
end
defp markdown do
sorted_items = items()
"""
#{unquote(event_url)}
# この記事は
- [#{unquote(event_title)}](#{unquote(event_url)})
- というイベントに参加していると**おもわれる**記事の一覧です
- 「参加ボタン」を押すのをお忘れなく
- [QiitaAzure](https://qiita.com/tags/qiitaazure)タグと[Azure](https://qiita.com/tags/azure)タグの両方がついていて、`created_at`が募集期間内になっている記事を集めて、LGTM数順に並べています
- 期間の境界のところは誤りがあるかもしれません
- そこはご愛嬌ということでお許しください :pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5:
# 総件数
#{Enum.count(sorted_items)}件 :tada::tada::tada:
# 総LGTM数 :lgtm::lgtm::lgtm::lgtm::lgtm:
#{
Enum.map(sorted_items, fn %{"likes_count" => likes_count} -> likes_count end)
|> Enum.sum()
|> Number.Delimit.number_to_delimited(precision: 0)
} :rocket::rocket::rocket:
# 全期間 :confetti_ball::military_medal::confetti_ball:
#{build_table(sorted_items)}
#{unquote(description)}
## QiitaAzure記事投稿キャンペーン
### 3月
https://qiita.com/official-events/a50e99d62dc62d68a9c9
### 4月
https://qiita.com/official-events/22637c675c61a797a24f
### 5月
https://qiita.com/official-events/5a0932fbeb1443ae1094
### 6月
https://qiita.com/official-events/885e4031d03c787eceab
### 9月
https://qiita.com/official-events/b7811ce1542be54e6efe
### 10月
https://qiita.com/official-events/8bc3780a142f8ee8effa
### 11月
https://qiita.com/official-events/2578ba1c949d056847df
# Wrapping up :lgtm: :qiitan: :lgtm:
- 自動更新は、[Elixir](https://elixir-lang.org/)というプログラミング言語がありまして、その[Elixir](https://elixir-lang.org/)で作られた[Nerves](https://www.nerves-project.org/)という[ナウでヤングでcoolなすごいIoTフレームワーク](https://www.slideshare.net/takasehideki/elixiriotcoolnerves-236780506)を使ってつくったアプリケーションで行っております
- [Nerves](https://www.nerves-project.org/)の始め方につきましては下記の記事が詳しいです
- [ElixirでIoT#4.1:Nerves開発環境の準備](https://qiita.com/takasehideki/items/88dda57758051d45fcf9)
- Raspberry Pi 2が定期的に記事を自動更新しているのであります
- [ソースコード TORIFUKUKaiou/hello_nerves](https://github.com/TORIFUKUKaiou/hello_nerves)
# 最後の最後に
## [Elixir](https://elixir-lang.org/)ってなによ:interrobang:という方へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/601aeb87-9d1d-6a9d-b30b-338507dc593e.png)
- :point_up::point_up_tone1::point_up_tone2::point_up_tone3::point_up_tone4::point_up_tone5: 2020/12/26時点くらいのスクリーンショット
- [Elixir](https://elixir-lang.org/)についてもっと知りたい方は下記の本:books:をオススメします
- [プログラミングElixir(第2版)](https://www.ohmsha.co.jp/book/9784274226373/)
- [Elixir実践ガイド](https://book.impress.co.jp/books/1120101021)
- [elixir.jp Slack](https://join.slack.com/t/elixirjp/shared_invite/zt-ae8m5bad-WW69GH1w4iuafm1tKNgd~w)の`#autoracex`というところに私は入り浸っておりますのでお気軽にお声がけください
- [NervesJP Slack](https://join.slack.com/t/nerves-jp/shared_invite/zt-9vteokip-iVAqi8TkT0ID_uK9dSqVHA)
- [Nerves](https://www.nerves-project.org/)やIoTが好きな愉快なfolksたちがあなたの訪れを歓迎します :tada:
- [勉強会が頻繁に行われています](https://twitter.com/piacere_ex/status/1364109880362115078)
- 私がよく参加している勉強会です
- [autoracex](https://autoracex.connpass.com/) 【毎週土曜〜月曜】 主催
- [Sapporo.beam](https://sapporo-beam.connpass.com) 【毎週水曜】
- [OkazaKirin.beam](https://okazakirin-beam.connpass.com) 【毎週木曜】
- [fukuoka.ex/kokura.ex](https://fukuokaex.connpass.com) 【毎月2~3回】
- [NervesJP](https://nerves-jp.connpass.com/) 【毎月1回】
- [Elixirコミュニティ の歩き方〜国内オンライン編〜](https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian)
- @kn339264 さん作 :clap::clap_tone1::clap_tone2::clap_tone3::clap_tone4::clap_tone5:
![FCOvBkAUYAE6mL8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131808/a277d0ea-2780-d9a3-4062-66d38b175125.jpeg)
(@piacerex さん作 :pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5:)
"""
end
defp build_table(items) do
Enum.with_index(items, 1)
|> Enum.reduce(
"|No|title|created_at|updated_at|LGTM|\n|---|---|---|---|---:|\n",
fn {item, index}, acc_string ->
%{
"title" => title,
"likes_count" => likes_count,
"created_at" => created_at,
"updated_at" => updated_at,
"url" => url,
"user_id" => user_id
} = item
acc_string <>
"|#{index}|[#{String.replace(title, "|", "|")}](#{url})<br>@#{user_id}|#{
created_at |> Timex.to_date() |> Date.to_string()
}|#{updated_at |> Timex.to_date() |> Date.to_string()}|#{
Number.Delimit.number_to_delimited(likes_count, precision: 0)
}|\n"
end
)
end
end
end
end
上記はゴチャゴチャあれこれ書いているからわかりにくいとおもいます。
骨格だけに削ぎ落としてみます。
大事なところは、単純なのです。
defmodule Qiita.Azure do
defmacro __using__(opts) do
item_id = Keyword.get(opts, :item_id)
quote do
def run do
...
unquote(item_id)
...
end
end
end
end
use Qiita.Azure
で共通部分を取り込んだ個別部分のモジュール(後述)は、run/0
関数を使えるようになります。
use/2は、第1引数がモジュール名、第2引数がキーワードリスト(厳密には違うかも?)です。
上記のbone.ex
では、use Qiita.Azure, item_id: "5105eed1aff115b8a4ef"
といった形式で呼び出されることを期待しています。
Qiita.Azure
から見た場合に、個別部分のモジュールのほうに追加をしてあげたいrun/0
関数はquoteの中に書きます。
item_id
等、quoteの外にある変数の値を使いたい場合には、unquoteして使用します。
これが骨格です。
quote: 引用する、引き合いに出す
unquote: 引用を終わらせる
個別部分
use Qiita.Azure
で共通部分を取り込んで、個別の事情をイベントごとにモジュールを作っています。
イベントが追加となるたびに以下のようなモジュールを夜なべしているわけです。
以下、2021/11/23時点で最新のイベントのものです。
defmodule Qiita.Azure.Certification do
use Qiita.Azure,
item_id: "5105eed1aff115b8a4ef",
title: "【毎日自動更新】マイクロソフト認定資格を取得する際の学習方法や経験談、おすすめ学習リソースなどを紹介しよう!(2021/11/11–2021/12/10) LGTMランキング!",
event_title: "マイクロソフト認定資格を取得する際の学習方法や経験談、おすすめ学習リソースなどを紹介しよう!",
event_url: "https://qiita.com/official-events/2578ba1c949d056847df",
description: """
# [Azure認定資格・試験](https://docs.microsoft.com/ja-jp/learn/certifications/browse/?Dev_TF=PET3035074&products=azure)と私
- :pray::pray_tone1::pray_tone2::pray_tone3::pray_tone4::pray_tone5: [AWS Certified Solutions Architect – Associate](https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/)なら持っています
- そろそろ期限がきれそう...
- このイベントをきっかけに[Azure認定資格・試験](https://docs.microsoft.com/ja-jp/learn/certifications/browse/?Dev_TF=PET3035074&products=azure)を取得してみようかとおもっています[^1]
- 私だけの感じ方かもしれません[^2]が、自分が書いた記事が他の方の記事からリンクされると、Qiitaの画面の上のほうで「**あなたの記事にリンクしました**」とお知らせがくることがありますよね
- あれが私はうれしいです
- イベントですし、お祭りということで勝手に応援させてください :lgtm::tada::tada::tada::lgtm:
[^1]: 思っています。あくまでもおもっています。
[^2]: 矢吹丈がそんな言い方を乾物屋の紀ちゃんにするシーンがあって、私は多用しています
""",
start: ~D[2021-11-10],
ending: ~D[2021-12-10]
end
上記のような調子でイベントごとにモジュールを作っています。
- Qiita.Azure.MicrosoftAI
- Qiita.Azure.MicrosoftBuild
- Qiita.Azure.MicrosoftIoT
- Qiita.Azure.MicrosoftJava
- Qiita.Azure.K8s
ソースコード
ソースコードの全体は、GitHubにあります。
一体、このプロジェクトは何なのでしょう?
いろいろなものがごった煮されていますをごった煮しています。
その張本人は私です。
複雑に入り組んだ現代社会の縮図であり、私自身の人生なのかもしれません。
もちろん複雑に入り組んだ現代社会に鋭いメスはいれていません。
参考記事
手前どもの熟成味噌をご披露いたします。
[Elixir]SlackのAPIを例にuseするものを自分で作って使ってみる
Wrapping up
『【毎日自動更新】マイクロソフト認定資格を取得する際の学習方法や経験談、おすすめ学習リソースなどを紹介しよう!(2021/11/11–2021/12/10) LGTMランキング!』等の記事制作の舞台裏をお見せしました。
私の趣味は、Qiita Advent Calendar 20213に毎日記事を投稿することです。
私の勝手な都合ですが、これを達成するためには11月のうちからある程度の記事を量産しておく必要があります。
11月中に半分は埋めておかないと12月がきついです。
11月中に半分埋めておけば、のこりは2日に一本のペースで書けばよく、これは理想です。
調査・構想に1日、次の日にそれを記事にまとめるという寸法です。
前日インプットしたものを翌日、思いの丈を爆発させてアウトプットするという格好です。
「書くことがない」という方に余計な老婆心から私が何を考えているのかお伝えしますと、「something x Elixir」でいくらでも量産できます。
somethingは、たとえば
などです。
またまた老婆心ながら、私が参加予定のQiita Advent Calendar 2021の各種カレンダーへのリンクとなっております。
(どの立場から言っているのか不明ですが)みなさんも奮ってご参加ください
Advent Calendar 2021 / IoT・ハードウェア / #NervesJPにまだまだ空きがあった4ので#NervesJPに投稿させていただきました。
「一人で何個も投稿するんじゃねえ!」というお叱りはごもっともですし、その際にはどこか別のカレンダーに移動いたします5。
人間五十年 下天の内をくらぶれば、夢幻のごとくなり。一度生を得て滅せぬ者のあるべきか
時は今あめが下知る五月かな
露と落ち露と消えにしわが身かななにはのことも夢のまた夢
親思ふ心にまさる親心 今日のおとづれ何と聞くらん
おまけ
Elixirを始めてみよう! とおもった、あなたに参考情報(クリスマス🎄プレゼント)を贈ります。
思い立ったが吉日です!!!
オススメの書籍
- プログラミングElixir(第2版) -- オーム社
- Elixir実践ガイド -- インプレス
- アルケミスト 夢を旅した少年 -- 角川文庫
Webアプリケーションを楽しむなら
IoTを楽しむなら
AIを楽しむなら
コミュニティ
-
elixir.jp Slack workspaceに参加してみてください
- マヂ、やさしい人ばっかりのコミュニティ
- あなたの困ったをきっと解決してくれるでしょう
- NervesJP Slack workspaceでは、NervesやIoTが好きな愉快なfolksたちがあなたの訪れを歓迎します
- たくさんのコミュニティがあります
- @kn339264 さん作の素敵な資料をご紹介します
- Elixirコミュニティ の歩き方〜国内オンライン編〜
@piacerex さん作
-
「動いています」の意。おそらく西日本の方言、たぶん。NervesJPではおなじみ。少し古いオートレースの映像ですが、実況アナウンサーが「針2イゴきます」とはっきり言っています。https://autorace.jp/netstadium/SearchMovie/Movie/iizuka?date=2017-01-04&p=5&race_number=11&pg= ↩
-
大時計の針のこと。針がイゴいてある地点まで到達すると選手はスタートを切って良い発走の合図。針がイゴきはじめると(おそらく)選手は緊張するし、スタートはその後のレース展開に大きく影響するので、車券を握りしめている観客たちがもっとも緊張する瞬間であるため、先の尖った鋭いものを連想させる針は緊張の暗喩としても言い得て妙。 ↩
-
「Qiita Advent Calendar 2021」に書くことが趣味です。「Qiita Advent Calendar 2022」に書くことまで趣味と言ってはいません。それに来年のことを言うと鬼に笑われます。 ↩
-
2021/11/23時点 ↩
-
ひとりアドベントカレンダーやればいいんじゃないの? それはごもっともですが、誰も読まれないところでこっそりシコシコやるのはさびししいです。自分自身ではない、だれか他の人がはじめてくださったアドベントカレンダーに投稿することに意味があるとおもっています。 ↩