hirapi's blog

ちゃんとしたふりをする

Prestoで配列の要素数を取得する

6.15. Array Functions and Operators — Presto 0.195 Documentation

cardinality(x) → bigint

Returns the cardinality (size) of the array x.

countとかsizeとかかなあと思ってたら違った、カーディナリティか……

入れ子配列のカラムを指定しても入れ子は展開されずに、なんていうかふつうにカウントされた。

PHPでTreasure Dataにpost2()

会社でTreasure Dataを使ってログの蓄積・集計をしていて、PHPからTreasure Dataにレコードを送ることがある。
そういうときはこのライブラリを使う↓↓

github.com

今まではこのREADMEにあるUsageのとおりこんな感じで送ってた↓↓

<?php

require_once __DIR__.'/vendor/autoload.php';

use Fluent\Logger\FluentLogger;
$logger = new FluentLogger("localhost","24224");
$logger->post("debug.test",array("hello"=>"world"));

ただこの間ちょっとレコード多くなるかもだから集計時間短くなるようにしたいなということがあって、こちらのブログを参考にtimeカラムに ID × 3600 みたいな任意の値を入れたくなった。

yebisupress.dac.co.jp

やってみて気づいたんだけど、こういう配列を前述の例のように post() に渡してもtimeカラムにはunixtimeが入ってしまう。

<?php

require_once __DIR__.'/vendor/autoload.php';

use Fluent\Logger\FluentLogger;
$logger = new FluentLogger("localhost","24224");
$logger->post("debug.test",array("time"=>7200)); // => timeカラムには普通に呼び出し時のunixtimeが入る

GitHubpost() のところを追ってみたところ、timeカラムの値は別途自動で入れられるらしい。

じゃあこのライブラリではtimeカラムに好きな値を入れられないかというと、そういうわけではない。

ここで post2()の出番。
冗談みたいな名前してるけどpublicなメソッド。

post() にはタグと配列を渡すけど、 post2() にはEntityクラスインスタンスを渡す。
post() も中身を見たら同じことをやっている。
Entityクラスのコンストラクタを見ると、第三引数にtimeっぽい値を渡せるとのこと。
post() の中身ではここに何も渡してないからデフォルトでnullになって、結果Entityオブジェクトのtimeプロパティにそのときの時刻が入る、というだけらしい。

というわけで自分でEntityクラスのインスタンスを作って post2() に渡してあげるとtimeカラムにちゃんとその値が入る。

<?php

require_once __DIR__.'/vendor/autoload.php';

use Fluent\Logger\FluentLogger;
use Fluent\Logger\Entity;
$logger = new FluentLogger("localhost","24224");
$entity = new Entity("debug.test",array("hello"=>"world"), 7200); // 第三引数にtimeカラムの値
$logger->post2($entity); // => timeカラムに7200が入る

レビューで先輩に教えてもらったとき何だその名前、と思ったけど合ってる。
どういう名前をつけるのがいいのかなあとちょっとだけ考えてみたけど、そもそもなんで送信用のメソッドを2つ作ったのかにもよるのかもしれない?

名前にちょっとだけウケたから投稿してみた。

Hanami公式入門ガイド日本語訳【5】Getting Started(4)

http://hanamirb.org/guides/1.1/getting-started/#writing-our-first-test

初めてのテストを書く

ブラウザでアプリケーションを開いたときに最初に目にする画面は、ルーティングが何も定義されていないときに表示されるデフォルトページです。

HanamiはWebアプリケーション開発手法としてビヘイビア駆動開発(BDD)を推奨しています。
最初の自作の画面を表示させるために、高次元の機能テストを書きましょう:

# spec/web/features/visit_home_spec.rb
require 'features_helper'

describe 'Visit home' do
  it 'is successful' do
    visit '/'

    page.body.must_include('Bookshelf')
  end
end

注意してほしいのは、Hanamiは最初からBDDの開発フローをサポートしていますが、特定のテスト用フレームワークに縛られているわけでもなければ、特別な統合システムやライブラリを備えているわけでもありません。

ここではMinitest(デフォルト)を使っていきますが、プロジェクトを作る際に --test=rspec オプションをつけることでRSpecを使うこともできます。
そうすればHanamiはRSpecのためのヘルパーやスタブのファイルを生成します。
(※ データベースのURLを微調整する必要があるときは .env.test を確認してください)

このコマンドを実行して、テスト用のデータベースにスキーママイグレーションしなければなりません:

% HANAMI_ENV=test bundle exec hanami db prepare

見ての通り、コマンドを実行する環境を指定するには環境変数 HANAMI_ENV をセットします。

リクエストを受ける

今テストを実行すると、失敗することがわかります:

% bundle exec rake test
Run options: --seed 44759

# Running:

F

Finished in 0.018611s, 53.7305 runs/s, 53.7305 assertions/s.

  1) Failure:
Homepage#test_0001_is successful [/Users/hanami/bookshelf/spec/web/features/visit_home_spec.rb:6]:
Expected "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Not Found</title>\n  </head>\n  <body>\n    <h1>Not Found</h1>\n  </body>\n</html>\n" to include "Bookshelf".

1 runs, 1 assertions, 1 failures, 0 errors, 0 skips

それではこのテストを通しましょう。
そのために必要な必要なコードをひとつずつ書き足していきましょう。

初めに足すのはルーティングです:

# apps/web/config/routes.rb
root to: 'home#index'

アプリケーションのルートを home コントローラの index アクションに指定しました(詳しくはルーティングの解説を見てください)。
次にindexアクションを作ります。

# apps/web/controllers/home/index.rb
module Web::Controllers::Home
  class Index
    include Web::Action

    def call(params)
    end
  end
end

これは何のビジネスロジックも実行しない空のアクションです。
それぞれのアクションには対応するビューがあり、ビューはRubyのオブジェクトであり、リクエストを満たすために追加する必要があります。

# apps/web/views/home/index.rb
module Web::View::Home
  class Index
    include Web::View
  end
end

アクションと同様にこのビューも空であり、テンプレートをレンダリングするだけです。
これが、テストを通すために編集する必要のあるファイルです。
先頭に "bookshelf" と追加するだけです。

# apps/web/templates/home/index.html.erb
<h1>Bookshelf</h1>

変更を保存し、テストをまた走らせてください。そうすると今度は通ります。
やったね!

Run options: --seed 19286

# Running:

.


Finished in 0.011854s, 84.3600 runs/s, 168.7200 assertions/s.

1 runs, 2 assertions, 0 failures, 0 errors, 0 skips

Hanami公式入門ガイド日本語訳【4】Getting Started(3)

http://hanamirb.org/guides/1.1/getting-started/#hanami-architecture

Hanamiのアーキテクチャ

Hanamiのアーキテクチャでは、同じRubyのプロセスで別々のHanamiアプリケーション(とRackアプリケーション)をホストすることができます。
これらのアプリケーションは /apps 以下にあります。
各アプリケーションが、ユーザー向けのWebページや管理画面、メトリクス、HTTP APIなどととしてプロダクトを構成することができます。

これらのパーツは、lib 以下にあるビジネスロジックに対する 分娩機構 (訳註:原文では" delivery mechanism ")です。
ここは、Modelが定義され、相互作用してプロダクトが提供する機能を構成するディレクトリです。

Hanamiのアーキテクチャクリーンアーキテクチャに強く影響を受けています。

Hanami公式入門ガイド日本語訳【3】Getting Started(2)

http://hanamirb.org/guides/1.1/getting-started/

前提知識

http://hanamirb.org/guides/1.1/getting-started/#prerequisites
始める前に、いくつかの前提を確認しましょう。
まず、webアプリケーション開発の基礎知識はあるものと仮定します。

また、Bundler、Rake、ターミナル操作、MVCモデルでのアプリケーション構築にも馴染みがあるものとします。

最後に、このガイドではSQLiteを使います。
もしこのガイドに沿って手を動かしたいなら、手元の環境でRuby 2.3以上、SQLite 3以上が動くことを確認しておいてください。

新しいHanamiプロジェクトを作る

http://hanamirb.org/guides/1.1/getting-started/#create-a-new-hanami-project
新しいHanamiプロジェクトを作るには、RubygemsからHanami gemをインストールする必要があります。
そうすると、新しいプロジェクトを作るための hanami コマンドが使えるようになります。

% gem install hanami
% hanami new bookshelf

(※ デフォルトでは、プロジェクトはSQLiteを使うように設定されます。
実際の開発のために、このようにしてデータベースエンジンを指定できます: % hanami new bookshelf --database=postgres

これで、カレントディレクトリに bookshelf という新しいディレクトリが作られます。
そこに何があるか見てみましょう:

% cd bookshelf
% tree -L 1
.
├── Gemfile
├── Rakefile
├── apps
├── config
├── config.ru
├── db
├── lib
├── public
└── spec

6 directories, 3 files

知っておかないといけないことはこちらです、

  • Gemfile は、(Bundlerを使って)Rubygemsの依存関係を定義します
  • Rakefile はRakeタスクを記述します
  • apps は1つ以上のRackアプリケーションを含みます
    ここに、最初に作られた Web と呼ばれるHanamiアプリケーションがあります。
    ここには、コントローラー、ビュー、ルーティング定義、テンプレートがあります。
  • config には設定ファイルがあります
  • config.ru はRackサーバー用です
  • db にはデータベーススキーママイグレーションがあります
  • lib にはビジネスロジックと、entityとrepositoryを含むドメインモデルがあります
  • public にはコンパイル済みの静的ファイルを置きます
  • spec にはテストがあります

先に、Bundlerで必要なgemをインストールしましょう。そうすると開発用のサーバーを立ち上げられるようになります。

% bundle install
% bundle exec hanami server

すると…… http://localhost:2300/ で初めてのHanamiプロジェクトの恩恵にあずかることができます!
こういう画面を見ることができるはずです。(訳註:画像は省略)

Hanami公式入門ガイド日本語訳【2】Getting Started(1)

http://hanamirb.org/guides/1.1/getting-started/

はじめよう

こんにちは。このページを読んでいるということは、あなたはHanamiについてもっと学びたいと思っていることでしょう。
すばらしい、おめでとう!
保守しやすく、安全で、高速で、テストしやすいwebアプリケーションを作る新しい方法を探しているのなら、きっと大丈夫です。

Hanamiはあなたのような人々のために作られています。

あなたがまったくの初心者だろうと経験豊富な開発者だろうと、 この入門はとてもハードかもしれない ということを先にお伝えしておきます。
私たちは時を経て「物事はこうあるはずだ」という予測を確立していきます、それを変えることは苦しいことかもしれません。 ですが、変化無しに挑戦は無く、 挑戦なしに成長は無いのです。

Hanamiの特徴がおかしく思えることもあるでしょうが、それはあなたがおかしいということではありません。
それは習慣の問題かもしれないし、設計に失敗しているのかもしれないし、あるいはバグかもしれません。

コミュニティの全員が、Hanamiをもっと良くするために日々全力を尽くしています。

このガイドでは、初めてのHanamiプロジェクトをセットアップし、簡単な本棚のwebアプリケーションを作ります。
私たちはHanamiの主要なコンポーネントに触れることになります、そしてそれら全てはテストの上に成り立っています。

もし一人ぼっちだと感じたり、くじけそうになっても、あきらめないで、私たちのチャットに加わって助けを求めてください。
きっと、喜んであなたとお話をする人がいます。

楽しんで。
Luca Guidi
Hanami開発者

Hanami公式入門ガイド日本語訳【1】Introduction

Hanami | Guides
英語のリハビリがでら和訳してみることにした。

はじめに

Hanamiとは?

Hanamiは、多くの小さいライブラリで構成されたRuby MVCフレームワークです。
Hanamiはシンプルで安定したAPI、最小限のDSLを有しています。また、過度な責務を負ったわかりにくいクラスよりも、純粋なRubyオブジェクトを使うことを重んじています。

明確な責務を持ったシンプルなオブジェクトを使うと、一般的にボイラープレートなコード(訳註:定型的なおまじないが繰り返し現れるコード)になります。
Hanamiを使えば、基本的な実装を保守している間、この余計な地道な作業を軽減することができます。

なぜHanami?

ここに、Hanamiを選ばざるを得ない3つの理由を示します:

軽量

Hanamiのコードは比較的短く、(実装に関係無く)全てのwebアプリケーションが必要とするようなことだけに関心を置いています。
Hanamiには様々なモジュールが備わっており、またその他のライブラリも簡単に組み込むことができます。

わかりやすいアーキテクチャ

"Rails way"に逆らっているように感じている人は、Hanamiをきっと評価することでしょう。
Hanamiにおいてコントローラーアクションはクラスから生成されています。そしてそれゆえに独立したテストを行いやすくなっています。
またHanamiでは、ビジネスロジックユースケースオブジェクト(いわゆるinteractor)に書くことが推奨されています。
Viewはテンプレートと分離しているため、内部にロジックを十分に書くことができ、また独立してテストすることができます。

スレッドセーフ

スレッドを使うと、アプリケーションのパフォーマンスを劇的に向上させることができます。
スレッドセーフなコードは簡単に書けるべきであり、Hanamiは(フレームワーク全体においても、その一部においても)スレッドセーフに実行されます。

ガイド

ガイドでは、高次のHanamiコンポーネントと、フルスタックアプリケーションの中でそれらの設定・活用・テストを行う方法を説明します。
ガイドで扱うのはBookshelfという想像上のプロダクトです。Bookshelfは読書体験をシェアし、本を購入することができるオンラインコミュニティです。
初めてのHanamiアプリケーションを構築するために、ガイドを始めましょう。