islands5 blog

日々起こったことを共有したり、思ったこと、勉強したことを書いていくブログ。普段はRailsやAWSを活用したWeb系の開発をやってます。

Go言語で先頭1文字を抜き出す

Go言語は好きなのですが、文字列の処理で定期的にハマるのが最近の悩み...

今回は先頭一文字を抜き出す方法。
単純に考えると

str := "この木なんの木気になる木"
fmt.Println(str[0])

#=> 227
とか言われる...

これは、文字の型がruneとかbyteとか色々あるGoさんならではの出力。

一度runeの配列に変換して、indexを指定、それをstringに戻すことで取得できる。 下のような感じ

str := "この木なんの木気になる木"
runeStr := []rune(str)
fmt.Println(string(runeStr[0]))

#=> こ

サンプルコードは以下で実行できます。

The Go Playground

Go言語で特定の文字列の位置を検索する(javascriptのindexOf的な)

stringsというpackageの中にIndexというそれっぽい関数があるが、これはbyteとしての位置を返すためちょっと工夫が必要

package main

import (
    "fmt"
    "strings"
    "unicode/utf8"
)

func main() {
    text := "下手糞の 上級者への 道のりは 己が下手さを 知りて一歩目。"
    if i := strings.Index(text[0:], "己"); i > 0 {
        fmt.Println("byte-pos:", i, "rune-pos:", utf8.RuneCountInString(text[0:i]))
    }
}
// byte-pos: 42 rune-pos: 16

半角スペースはbyteのカウントには含まれてないし結構ハマった

The Go Playground

お金は細部より流れだ!『お金の流れが一目でわかる! 超★ドンブリ経営のすすめ』の読書感想

先日、はじめて「経営セミナー」なるものに行ってみた時に参考文献として紹介されていた本

これまであまり意識したことはなかったけど、売上、利益がどうとかって、社内で意見を通すためには強力な武器になる。
知ってはいたんだけど、ちゃんと勉強したことなかったので、本書で入門してみました。

たぶん初心者の人でも読みやすいと思う。
覚えること20個ないくらい。
つるかめ算ができれば、理解できると思う。

筆者がしきりに訴えているのは

会社の数字が正確に読めることと、正しい経営判断ができることは、別の能力

会社として生存していくためには、利益が必要で、その利益も実は色々引かれるんだよ。
最後に残るのはこんな感じで、ここから次の投資ができる。

というのが、1つの図になりビジュアルで理解できる。
ヤバイ状態もビジュアル化される。

とてもスッキリしてわかりやすく、いいなと思った。

年商◯億に騙されるな!
会計について気になっている人はぜひオススメの一冊です。

お金の流れが一目でわかる! 超★ドンブリ経営のすすめ―――社長はこの図を描くだけでいい!

お金の流れが一目でわかる! 超★ドンブリ経営のすすめ―――社長はこの図を描くだけでいい!

jsでよくある「関数読み込まれてない」問題の対処法

実行順序とか考慮して使わないようにすべきなんだけど、どうにもならない時

var repeat = setInterval(function(){
  if(typeof(hogeFunc == "function") {
    hogeFunc()
    clearInterval(repeat)
  }
});

こいつが助けてくれるときがあります。

Promiseオブジェクトを使ったらAPI周りの処理がスッキリした

f:id:fiveislands:20180125213553p:plain

かなり前からPromiseオブジェクトの存在は知ってたのですが、ほとんど気にしないでほったらかし状態に...
ただ、必要な状態に出会ってしまったのと、そのときに初めてPromiseについて便利さが理解できた気がするので共有します

先に結論
要件: リクエストした内容を特定の要素のhtml内に入れるという処理を行う
よくやること: APIへのアクセスのcallbackに要素の変更に関するコードを入れる
対応: Promiseを使ってやれば、APIへのアクセスと要素の変更をキレイに分離でき、可読性も上がって嬉しい!!
という内容です

最終的なコードは

function requestHogeAPI(){
  return Promise.new (function(resolve, reject) {
    $.ajax({
      url: "/api/v1/hoge"
    })
    .done(function(res){
       resolve(res);
    })
    .fail(function(e){
       reject(e);
     });
  })
}

// main
requestHogeAPI()
.then(function(data){
  $("#hoge").html(data)
})
.catch(function(e){
  console.log(e)
})

上記のコードは、APIへのアクセスと要素の変更が別の処理にわかれてます。
このコードに至るまでに僕が辿った道筋をまとめてみました。

未知との遭遇(jsビギナースタイル)

// resは<div>hello world</div>が帰ってくるイメージです
function fugaSetResponse() {
  $.ajax({
    url: "/api/v1/hoge"
  })
  .done(function(res){
    $("#fuga").html(res);
  })
  .fail(function(e){
    console.log(e);
   });
}


//main
fugaSetResponse()

ajaxのレスポンスにjqueryが直接書いてるパターン
大なり小なり、よくあるコードなんじゃないかな?と思います。
みんなここを一度は通りますよね?よね???(俺だけ???)

抽象化1(セレクタスタイル)

function elemementSetResponse(elem){
  $.ajax({
    url: "/api/v1/hoge"
  })
  .done(function(res){
    $(elem).html(res)
  })
  .fail(function(e){
    console.log(e)
  });
}

//main
elementSetResponse("#piyo")

セレクタを引数として渡してそいつに適用するパターン
まだapiと要素の変更が一緒になってて、気持ちわるい

抽象化2(コールバックスタイル)

hogeapiへのリクエスト結果に他の処理を加えたい

function elementProcessor(callbackFunc){
  $.ajax({
    url: "/api/v1/hoge"
  })
  .done(function(res){
    callbackFunc(res)
  })
  .fail(function(e){
    console.log(e)
  });
}

function changeHoge(res){
  $("#hoge").html(res);
}

//main
elementProcessor(changeHoge)

与える関数を変更すれば要素も変更できるし、処理も変更できるし少しうれしい感じ
あとなんかjsっぽいw
...changeHogeは他のところで使うのだろうか??
無名関数渡してもいいよね

抽象化3(コールバックセレクタスタイル)

こちらは僕が最初書こうとしてたコード

function elementProcessor(callbackFunc, elem){
  $.ajax({
    url: "/api/v1/hoge"
  })
  .done(function(res){
    callbackFunc(res, elem)
  })
  .fail(function(e){
    console.log(e)
  });
}

function changeElement(res, elem){
  $(elem).html(res);
}

//main
elementProcessor(changeElement, "#piyo")

ただ、callbackに渡すために親に引数追加ってちょっとやり過ぎじゃね?って思ったんですよね

抽象化4(やっぱりプロミス!!)

function requestHogeAPI(){
  return Promise.new (function(resolve, reject) {
    $.ajax({
      url: "/api/v1/hoge"
    })
    .done(function(res){
       resolve(res);
    })
    .fail(function(e){
       reject(e);
     });
  })
}

// main
requestHogeAPI()
.then(function(data){
  $("#hoge").html(data)
})
.catch(function(e){
  console.log(e)
})

thenの中は好きなコード書いてOK
requestHogeAPIのコードはわりと色んなところで使用できると思うし、役割の分割もきっちり出来てると思う。

結論

Promiseを使って上手くやれば、APIへのアクセスと要素の変更をキレイに分離できて関数の再利用性が上がるし可読性も上がって嬉しい!!

ではではm( )m

社内ツールとherokuの相性は最高だ!

gitを使える人だったら、サーバーの設定をせずにしかも無料で使えちゃうheroku

今年に入り、業務改善のためcsvを特定の形式に変換するためのツールを作ってたりするのですが、ほんとに便利だと関心する。
エンジニアとしてはこのようなプログラマに感謝されるサービスを一度は作りたいなと

簡単認証つき社内ツール作成の際にハマった点のメモを

使用したフレームワーク

ruby2.5.0 => 12月末リリースのバージョンですが、herokuですでに対応済み rails5.1.4

要件

・最低限の認証
・ファイルを選択したら変換される

ベーシック認証

僕はよくnginx側でベーシック認証をかけるのですが、railsのapplication_controllerで設定しました。

http_basic_authenticate_with :name => ENV['USERNAME'], :password => ENV['PASSWORD'] if Rails.env == "production"

をコードに追加して、
herokuアプリケーションに環境変数を登録します。

$ heroku config:set USERNAME=username
$ heroku config:set PASSWORD=password

これでベーシック認証をかけられます。

データベースと接続しないクラスの作成

csvを特定の形式に変換するだけなので、データベースに保存する内容は特にありません。
そのため、modelを作成してロジックを追加するのはちょっと違うな~なんて考えたものだから少しハマった。
しかもRails5のproduction環境でしか発生しないというから皆さん気をつけてください。(既存のサービスをRails4からアップデートする人も気をつけたほうがいいかもです)

最初

config.autoload_paths += %W(#{config.root}/lib)

productionではクラスを読み込んでくれない

config.enable_dependency_loading = true
config.autoload_paths += %W(#{config.root}/lib)

なぜproductionで読み込んでくれないんだ(逆なら焦らないのに)w

Rails5: production環境でのAutoloadの廃止 - Qiita 廃止になるのはいいんだけど、データベースに接続しない系のクラスってみんなどこにまとめてるんだろ

少し気になった小企業のプログラマでした。

ではでは~

文字コードにはマジ、マジで気をつけよう(ていうか不注意)

csvを変換するツールの作成依頼をうけて、特に難しい処理もなかったので2つ返事でOKしました。

やりたいこと 生csv -> よしなに集計 -> 別サービスにインポート用のcsv

最初にもらったcsvをベースに正解状態になるようにスクリプトを書いていきます。 ほどなくしてスクリプトの作成は終わり、念のため別の生csvでスクリプトを試したときに悲劇は起こりました。

_人人人人人人人人人_
> 計算が合わない <
 ̄YYYYYYYY

そんなバカなと思って、ロジックの見直しなど色々行ったのですが、最初のファイル以外計算が合わないのです。

まさかな~と思ってnkfでファイルの文字コードを調べたところ...

% nkf --guess data/test4.csv                                                                                                                                                                                                                                     (git)-[master]
CP932 (CRLF)

CP932という結果
さっきまでエラー出てなかったような...
上の方をおそるおそるスクロールすると

[19] pry(main)> csv_data = CSV.read("data/test4.csv", headers: true)  
ArgumentError: invalid byte sequence in UTF-8
from /usr/local/lib/ruby/2.5.0/csv.rb:2046:in `=~'

ちゃんと出てました。。。

完全に僕の確認不足で、横着してpry上でずっとテストしていたので、読み込みに成功したcsv_dataを参照したままプログラムを実行してましたorz
pryで粘る際は、定期的にresetコマンドを実行して、環境をクリーンにしましょう

ちなみに文字コードを考慮してcsvを開く場合はこちらです。

[76] pry(main)> csv_data = CSV.read("data/test4.csv", headers: true, encoding: "CP932:UTF-8")  
=> #<CSV::Table mode:col_or_row row_count:1121>

みなさんもお気をつけください

ではでは~

VueJSメモ[ショートハンド]

Vueを触っていると
v-on:click
v-bind:id
的な記述をよく使います。

これにはショートハンドがあって、
v-onは@
v-bindは:
に置き換えられます。

よく使うものにショートハンドが存在するのはうれしいですね :)

jp.vuejs.org

VueJSメモ[算出プロパティ、ウォッチャーの使い所勘所]

computed(算出プロパティ)

・html内にロジックを記述するのを防ぐ ・プロパティが変更されてなかったら、キャッシュを返す

このあたりは速度改善などで肝になりそう。

https://jp.vuejs.org/v2/guide/computed.html#%E7%AE%97%E5%87%BA%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3-vs-%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89

watch(ウォッチャー)

・データの変更に対して反応 ・プロパティの変更をトリガーにして非同期処理とか実行するならここ

https://jp.vuejs.org/v2/guide/computed.html#%E3%82%A6%E3%82%A9%E3%83%83%E3%83%81%E3%83%A3

VueJSメモ(v-on、イベント修飾子)

今日はイベントの発火の話

Vueはv-on:event_nameで指定した要素で発火したイベントをキャッチすることができる。
(event_nameに入るのはこのあたりのイベントイベントリファレンス - Web 技術のリファレンス | MDN)

例えばクリックした時にalertを出すサンプル

通常のイベントの動作を修飾する機能もある。
特定のキーのみ発火させたい場合、eventを子要素に引き継ぎたくない場合など

例えばエンターキーをkeydownした時だけ関数を実行してほしい

イベントハンドリング — Vue.js