みずラテ

牛乳と水を2対1で。

rbenvでRubyの最新バージョンがインストールできない

分かれば簡単な話でしたが、解決策をメモしておきます。

事象

rbenvでRubyの最新バージョン2.7.1をインストールしようとしたところ、rbenv install -lしても最新バージョンがリストに表示されなかった。
f:id:taris777:20200415135826p:plain

解決策

まずは、インストールしたい最新版を指定して、rbenv install 2.7.1と打ってみる。
すると、

$ rbenv install 2.7.1
ruby-build: definition not found: 2.7.1
See all available versions with `rbenv install --list'.
If the version you need is missing, try upgrading ruby-build:
  cd /home/myproject/.rbenv/plugins/ruby-build && git pull && cd -

となった。解決策は英語でそのまんま書いてあります。最終行のコマンドを打つだけ。
cd /home/myproject/.rbenv/plugins/ruby-build && git pull && cd -
これでrbenvの最新版が取得できました。

あとはもう一度、rbenv install -lしてみると、、
f:id:taris777:20200415140237p:plain

はい、2.7.1が取得できました。これでrbenv install 2.7.1すると無事インストールされました。

結論

rbenvの最新版をまずはgit pullしましょうということでした。

今回は以上です。

3歳児がリモートワークを初めてできるようになったこと

コロナウイルスの影響を受けて、我が家でもリモートワークが始まりました。

妻もリモートワークできるようになった為、保育園に行かせるのを止め、自宅でみる事にして1週間が経過しようとしています。

自宅で見るとはいえ、僕も妻も仕事をしなくてはいので、ほとんどみていることが出来ません。娘には申し訳ないですが基本的には一人で遊んでもらっています。

一番集中してくれるのはやっぱりパソコンを与えて、Youtubeを見させること。これで1時間くらいは何も言わずに見てくれることがあります。

アンパンマンの人形遊びをしているyoutuberの動画や、はらぺこあおむしの動画なんかを好んで見ていましたが、ここ数日は「ペッパピッグ」という豚の家族のアニメが大好きになりました。ほんわかしたストーリーが多く、日常系として親が見ても楽しいです。

元々は英語のアニメなので、自分で勝手にyoutubeを操作して次の画像に進んでいて、気がつくと英語版を見ていたりします。(理解している?)

そんな娘ですが、親が見ていないうちに違う動画に切替しているようで、気になって操作を横から見てみると

  • ドラッグ&ドロップの操作
  • スペースボタンでの動画再生・停止

が出来るようになっていました。特に教えてもいないのに親がやっているのを見て出来るようになったのか。
さすがデジタルネイティブ世代。将来が楽しみです。

まだリモートワーク&家での保育を初めて数日ですが、たまに仕事を中断させられることもありますが、総じてなんとか回っているという感じです。
これから数週間単位で自宅保育となった時に、娘のストレスが増えていくのか、なんだかんだうまく出来ていくのか、わからないですが注視していきたいと思います。


【Rails】JSONデータをhashにしてdry-structでオブジェクト化する

Rails初心者なので他にいい方法がある気がするのですが、最新知ったやり方をまとめてみます。

やりたいこと

APIなどで取得したJSONデータをそのままRubyのオブジェクトに落とし込んで処理に使いたい。

やり方

今回はDry-rbシリーズというGemの中のdry-structとdry-typesを駆使して実装したいと思います。

環境

Rails 6.0.2
Ruby 2.5.7

dry-structのインストール

Gemfileに以下を追記してbundle installしましょう。
勝手にdry-typesやその他必要な関連Gemも一緒にインストールされると思います。

gem 'dry-struct', '~> 0.5.0'

bundle install

初期設定

dry-rb.org
こちらのサイトにあるようにどこかに初期設定を入れる必要があります。
私は、initializers配下に新規にtypes.rbを作成して配置しました。

module Types
  include Dry.Types()
end

データの準備

今回簡単なテストデータとしてこんなものを用意しました。
何かしらのAPIをコールしたら、レスポンスbodyにステータスと、著者と代表作が3冊取得できたという想定です。
booksの部分がネストしているというのがミソです。

json_data = <<EOS
{
  "status": "0",
  "message": "",
  "author": {
    "id": "auther111",
    "name": "akutagawa"
  },
  "books": [
    {
      "id": "book111",
      "name": "rasho-mon",
      "publishedyear": "1915"
    },
    {
      "id": "book222",
      "name": "kumonoito",
      "publishedyear": "1918"
    },
    {
      "id": "book333",
      "name": "ababababa",
      "publishedyear": "1923"
    }
  ]
}
EOS

クラスを作成する

作るクラスは3つ。Author, Book, そして2つをまとめたGetAuthorInfoというクラスです。
全てのクラスでdry-structを使うので、Dry::Structを継承します。

class Book < Dry::Struct
  attribute :id, Types::String
  attribute :name, Types::String
  attribute :publishedyear, Types::String
  def title_call
    "この本は、" + name + "だよ。"
  end
end

class Author < Dry::Struct
  attribute :id, Types::String
  attribute :name, Types::String
  def my_name
    "私の名前は、" + name + "である。"
  end
end

class GetAuthorInfo < Dry::Struct
  attribute :status, Types::String
  attribute :message, Types::String
  attribute :author, Author
  attribute :books, Types::Array.of(Book)
end

使ってみる

JSONデータをhash化するのは標準のparseメソッドで。
気をつけなきゃいけないのは、hash化するときのキーは文字列ではなくて、シンボルにする必要があるというところ。(dry-structの仕様です。)
あとは、パースしてhash化されたものを引数にnewしてあげると、オブジェクトになっています。

parsed_data = JSON.parse(json_data, symbolize_names: true)
autherInfo = GetAutherInfo.new(parsed_data)
autherInfo.auther.myname

ネストしていた部分はbookオブジェクトとして配列から取り出せるようになっていますし、配列として.sizeなんかも普通にできます。

autherInfo.books.size
autherInfo.books[1].title_call

以上です

全然dry-rbのサンプル出てこないから大変でした。JSONデータをrubyオブジェクトとしてRailsで使用するのって普通どうやってやっているんだろう。

とりあえず今回は以上です。

Ruby on Rails 6 実践ガイド impress top gearシリーズ

Ruby on Rails 6 実践ガイド impress top gearシリーズ

  • 作者:黒田 努
  • 発売日: 2019/12/20
  • メディア: Kindle版

やる前からできないという3歳児

うちの娘の話です。

うちの娘の特徴として、結構な頻度で何か新しいことを一緒にやろうと言った時に「できない〜」と言ってやろうとしません。
例えばボールを蹴るといった動作であってもです。

「とっても簡単だよ〜」「楽しいよ〜」

と誘ってみても、楽しさを自分なりに演出してみても、

「できないよ〜」

と言ってやろうとしません。別にめんどくさがっている感じではなく、本当に出来ないと思い込んでいる風です。

どうしたものかなー

と考えてネットで同じ悩みを持っている人の記事を読んでみるとこんなポジティブな捉え方をされている人がいました。

「出来ないと言えるのは頭が良いということ」


つまり、自分の今の能力と、ある動作に求められている能力を比較して、自分の能力が足りていないと判断できているとのこと。


なるほどと思いました。未知の動作に大して冷静に出来る出来ないの判断をしているということか。


例えば、

僕は泳げますし、垂直跳びとか、ケンケンパとかは難なくできます。これは自分が出来ると思っているし、実際に出来た経験があります。

でもバク転はやったことありません。自分で出来ないとも思っています。体をどう動かせば良いのか全くの未知が故、自分には出来ないと思っています。
でも、TikTokとかの動画でたまに1時間でバク転ができる動画みないなのが出てきます。ステップバイステップで少しずつ体の動かし方を体に覚えさせていって、最終的には本当にバク転が出来るようになっているというものです。

これと近いのかなと思い当たりました。

うちの娘は何をするにも、やったことがなくて未知の動作を何も考えず試してみることができず、まず頭で出来るできないの判断が先にきてしまうんじゃないかとお思います。ちょうど大人が新しい運動動作に躊躇するように。

僕にとっては簡単だと思える動作でも、娘にとってはバク転くらい難しいものと考えている。だってやったことないから。

順番を追って、自分が出来ると思える範囲で少しずつ出来ることを増やしていって初めて、それが出来ると思える。

とすると、これは時間がかかります。少しずつステップバイステップで出来ることを増やして上げて、できないと言っている動作のちょっと簡単な動作から一緒にやって、というのを根気よく続けていかなければならない。

躊躇なく挑戦できる性格の方が習得は早いと思います。世の中トライアンドエラーでしか上達しないことばかりですからね。


それでも

子供の特性がわかれば対応も考えようがあります。
できないと言っているのにも理由がある。大人目線では「なんで出来ないというの?」と思うことでも、子供目線では出来ないと思えることがある。こう考えるだけで、楽になる気がします。


とりあえずそう思ってもう少し観察してみます。

今日は以上です。

AWS SAA-C01に滑り込みで合格しました

会社でAWSサービスを触り始めて2ヶ月くらい経ち、そろそろ受けてみようかなと思い立ったのが2月中旬。

試験の内容を調べてみると、なんと現在のソリューションアーキテクトの試験は3月22日で終わり、新しいバージョンのSAA-C02に切り替わるということが判明。

新しいバージョンでも特に難しさは変わらないという記事もありましたが、試験問題の対策的に広く出回っている現行C01の方を進めている人が多かったので、それならば受けてしまおうと思って受けました。この時点で試験まで3週間でした。

模擬試験を受ける

とりあえず模擬試験を受けます。2000円払って受けた結果は65%

3週間頑張れば受かりそうで受からなそうなちょうどいいラインでした。個人的にこういう模試で合格ラインに最初から入ってしまうと勉強しなくなるので。

教科書をとりあえず読む。

メルカリで安く買えたのでこの教科書を読んでみました。試験範囲を網羅的に広く薄くカバーしているような本で、正直読んで眠くなりましたが知らないAWSサービスの概要を掴むことができました。


問題集サイトでひたすら問題を解く

www.whizlabs.com

こちらのサイトで「Practice Tests」を買うと、約2000円くらいで600問くらい解くことができます。ひたすらここで問題を解いていきました。65問解いて、間違った問題の解説をみて、もう一度解いてほぼ100%正解したら次の65問という風に進めていって、流石に全部解けなかったですが、500問くらいは解きました。

全て英語なので、ちょっと読む時間はかかりますが、これで慣れておくと日本語の問題がさらさら読めて解く時間が早くなると思います。わからない単語はGoogle翻訳の拡張機能を入れてその場で翻訳してしまえば良いです。

最後の1週間くらいで、初見の問題でも80%平均でとることができるようになってきたのでまあ大丈夫だろうという自信になりました。

テストを受ける

予定していた時間よりもちょっと早くついてしまったのですが、受付した人から順番に初めて良いやつだったので、20分くらい早く始まりました。

全部解いて見直しをして、絶対正解していると思えるのが65問中45問、自信はないけど大丈夫だろうというのが15問、全く自信がないのが5問くらいという感じだったので、残り1時間残して回答終了。

すぐ結果が出ると言われてましたが、その前にアンケート9問が出てきてずっこけ。

アンケート解答が終わると画面に結果が出ます。

合格!

よかった〜

スコアレポート

5日以内にサイト上から結果が見れるということでしたが、その日の夜中0時に確認したらスコアが出ました。
スコアは860点で、自己採点でもそのくらいかなーと思っていたので、よかったです。

次は

デベロッパーかいきなりDevOpsか迷ってますが、上に書いた問題集サイトでDevOpsの無料テストをちょっと覗いてみたら個々のサービスを相当使っていないと解けなさそうだったので、業務でもう少し精通してから受けてみようと思います。半年後くらいかな。


今回は以上です。

AWS SAMでAPI GatewayからSQSにメッセージを溜める

今回はAWS SAMを使って初めてのサーバーレスを体験してみようと思います。

具体的にはAPI GatewayにPOSTされたメッセージをそのままSQSに送信して溜め込むというのをSAMのテンプレートを作ってコマンドでデプロイしてみるところまでをやってみます。

前提

前回、SAMの開発環境をDocker上に構築していますので、今回はそのDocker上での作業が前提となります。

djandjan.hateblo.jp

sam init

まず初めにやることはsam initですね。Docker remoteしているVSCode上のターミナルで以下を実行します。

sam init -n firstApp

すると対話形式で構築が始まります。

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Which runtime would you like to use?
        1 - nodejs12.x
        2 - python3.8
        3 - ruby2.5
        4 - go1.x
        5 - java11
        6 - dotnetcore2.1
        7 - nodejs10.x
        8 - python3.7
        9 - python3.6
        10 - python2.7
        11 - java8
        12 - dotnetcore2.0
        13 - dotnetcore1.0
Runtime: 2

AWS quick start application templates:
        1 - Hello World Example
        2 - EventBridge Hello World
        3 - EventBridge App from scratch (100+ Event Schemas)
Template selection: 1

最初の質問はCustom Templateを持っていないので、Quick Startの方の1を選択。
次の質問はlambdaで使用する言語ですが、今回はPythonを選択しました。
最後はサンプルテンプレートの選択で1を選びました。

これで、firstAppというディレクトリが作成され、中に最初の一式が入っていると思います!

.
|-- README.md
|-- events
|   `-- event.json
|-- hello_world
|   |-- __init__.py
|   |-- app.py
|   `-- requirements.txt
|-- template.yaml
`-- tests
    `-- unit
        |-- __init__.py
        `-- test_handler.py
4 directories, 8 files

ただ、今回使用するのはtemplate.yamlだけなので、それ以外は全て消してしまいました。

.
`-- template.yaml

0 directories, 1 file

あらら、、めちゃくちゃシンプルになってしまった。まあいいや。早速、templateをいじっていきます。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  firstApp
  send message to SQS via API Gateway.

Resources:
  # SQSの作成
  SampleQueue: 
    Type: AWS::SQS::Queue
    Properties: 
      QueueName: "SampleQueue"
      MaximumMessageSize: 1024 # 最大メッセージサイズ(バイト)
      MessageRetentionPeriod: 604800 # メッセージ保持期間: 7日
  
  # API Gatewayにアタッチするロール SQSへのSendMeessage権限を持たせる
  SampleIAMRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Join
                - ""
                - - !Ref AWS::Region
                  - "RoleSendMassageToSQS"
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: apigateway.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: send_message_to_sqs
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - sqs:SendMessage
                Resource: !GetAtt SampleQueue.Arn
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: '*'
  
  # API Gatewayの設定
  SampleAPIGateway:
    Type: "AWS::ApiGateway::RestApi"
    Properties:
      Name: Sample_API_Gateway
      ApiKeySourceType: HEADER
      EndpointConfiguration:
        Types:
          - REGIONAL
  ApiMethod:
    Type: "AWS::ApiGateway::Method"
    Properties:
      RestApiId: !Ref SampleAPIGateway
      ResourceId: !GetAtt SampleAPIGateway.RootResourceId
      ApiKeyRequired: true
      AuthorizationType: NONE
      HttpMethod: POST
      Integration:
        Type: AWS
        Credentials: !GetAtt SampleIAMRole.Arn
        IntegrationHttpMethod: POST
        IntegrationResponses:
          - StatusCode: '200'
        PassthroughBehavior: NEVER
        RequestParameters:
          integration.request.header.Content-Type: '''application/x-www-form-urlencoded'''
        RequestTemplates:
          application/json: Action=SendMessage&MessageBody=$input.body
        Uri: !Join
          - ''
          - - 'arn:aws:apigateway:'
            - !Ref 'AWS::Region'
            - :sqs:path/
            - !Ref 'AWS::AccountId'
            - /
            - !GetAtt SampleQueue.QueueName
      MethodResponses:
        - ResponseModels:
            application/json: Empty
          StatusCode: '200'

aws 接続設定

aws configureコマンドで接続設定をしていきます。
予め、AWSマネジメントコンソールでユーザーを作成し、アクセスキー IDとシークレットアクセスキーをメモしておいてください。

aws configure
AWS Access Key ID [None]: <<自分のアクセスキーID>>
AWS Secret Access Key [None]: <<自分のシークレットアクセスキー>>
Default region name [None]: ap-northeast-1
Default output format [None]: 

S3バケットを作成する

SAMがデプロイ用に使用するバケットを事前に作成しておきます。

aws s3 mb s3://sam-cli-bucket-xxxxxxxx

名前は適当につけて良いですが、全世界でユニークな名前が必要なので、上記のバケット名だとできないかもしれません。各自自分でバケット名は設定してください。

ビルドする

コマンド一発

sam build

デプロイする

こちらもコマンド一発

sam deploy --stack-name firstApp --s3-bucket sam-cli-bucket-xxxxxxxx --region ap-northeast-1 --capabilities CAPABILITY_NAMED_IAM

こんな感じでSuccessfullyとなったら成功!
f:id:taris777:20200218001314p:plain

試してみる

早速試してみましょう。
AWSマネジメントコンソールにログインして、CloudFormationを開いてみてください。
f:id:taris777:20200218001455p:plain
新しいスタックが作成されています。

続いてAPI Gatewayに行ってみてください。
こちらも新しい、Sample_API_GatewayというAPIが作成されていると思います。
このAPIを開いてリソース→POSTをクリックすると、こんな感じの設定画面になります。

f:id:taris777:20200218001649p:plain

ここで、テストをクリックして、リクエスト本文に以下のように入力してテストボタンを押してみると・・・

{
  "body": "this is a test."
}

f:id:taris777:20200218001840p:plain

SendMessageResponseが返ってきたら成功していると思います。

AWSマネジメントコンソールでSQSを開いてみると、

f:id:taris777:20200218002027p:plain

1件入ってる!ポーリングして中身を確認してみても、さっきテストでリクエストを投げたものがそのまま入っています!

f:id:taris777:20200218002114p:plain

おわりに

というわけで、API GatewayからSQSにメッセージを入れ込むところまでSAMでやってみました。
実戦で使うにはAPIのデプロイをしなくちゃいけないのですが、それはまた次回にやってみようと思います。

今日は以上です。

図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書

図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書

  • 作者:小笠原 種高
  • 出版社/メーカー: 技術評論社
  • 発売日: 2019/11/07
  • メディア: 単行本(ソフトカバー)

WSLでUbuntuにrubyをインストールしようとしたらno acceptable C compiler foundエラー

WSLの設定をしているときにつまづいたエラーについてメモしておきます。

事象

WSLで Ubuntuの開発環境構築をしようとして、rbenvでrubyをインストールしようとしたところ、以下のようなエラーが発生。

checking for ruby... false
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking target system type... x86_64-pc-linux-gnu
checking for gcc... no
checking for cc... no
checking for cl.exe... no
configure: error: in `/tmp/ruby-build.20200217084852.643.IxacPV/ruby-2.6.5':
configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details

対応

エラーに書かれている通りなのですが、gccというCコンパイラがないためにrubyのbuildができませんよということみたいです。
なので、gccをインストールすれば解決です。

ググってみると、ubuntuにはbuild-essentialというのがあって、開発に必要なコンパイラ群のおまとめセットのようなものみたいですので、今回はこちらを入れてみました。

sudo apt-get update
sudo apt install build-essential

これで無事gccが入りました。

あとは、いつも通りrbenvからrubyをインストールします。

rbenv install 2.6.5

無事通りました〜

まっさらなlinux OSだと最初に必要なもの忘れがちですよね。エラーをよく見て書かれている通りに対応するのが大切。

以上です。