鶏頭のプログラム

Ruby, Javascript, C言語, SQLなどのプログラミング

Crystal言語のコントリビューターになりました。

前回の記事でCrystalのArrayにはsliceがないという紹介をしました。
Crystal言語はここが違う(配列編) - 鶏頭のプログラム

ですので、今回はCrystal言語のコントリビューターとしてslice!関数相当の関数を作成し
コミットしました。

manastech/crystal · GitHub

当初、slice関数とslice!関数を用意してコミットしたのですが
delete_atという似た関数が存在するのでそっちに追加するように
言われたのでそっちを拡張しました。

ですので、Rubyのslice!関数に相当するものとしてdelete_at関数が使用できるように
なるはずです。リリース0.7.8で追加されるかと思います。

次はflatten!関数を追加しようと思っています。

追記------------
flatten!はいらないということでした。確かに言われてみればその通りだなと思う内容でした。

Crystal言語はここが違う(配列編)

RubyのコードをCrystalに置き換えてみる - 鶏頭のプログラム
に引き続きCrystalのことを書いていきます。

今回は配列Arrayについて記載します。
詳しくはここ
Array: http://crystal-lang.org/api/index.html#http%3A//crystal-lang.org/api/Array.html

HashやArrayに存在しない値を指定するとRubyではnilが返ってきますが
CrystalではExceptionが発生します。

arr = [1,2,3]
puts arr[3]

h = { a: "hello" }
puts h[:b]

このコードの場合、実行すると

Index out of bounds (IndexError)
Missing hash value: :b (KeyError)

というエラーが発生します。Rubyのようにnilを返したい場合は

arr = [1,2,3]
puts arr[3]?

h = { a: "hello" }
puts h[:b]?

というように記載します。

以下、RubyにはあってCrystalには存在しないArrayクラスのメソッドを記載します。
collect → mapで代替可能
collect! → map!で代替可能
drop
drop_while
eql? → かわりにequals?という関数が存在し、自分で定義することが可能です。
flatten
flatten!
include? → includes?という関数は存在します。
keep_if -> select!で代替可能
rassoc
repeated_combination
repeated_permutation
rotate
slice
slice!

個人的にはsliceがないのが残念な感じがしますが、ほとんどのメソッドが実装されています。

追記---------------------
0.7.8からdelete_atが実装されてslice!の代わりに使用できる予定です。
また、rotate, flattenの一部, repeated_combinations, repeated_permutationsは実装されるようです。

RubyのコードをCrystalに置き換えてみる

Rubyライクに書けて
さらにコンパイルしてバイナリファイルを作ることができる
Crystalを触ってみました。

Crystalのサイト: Crystal
Crystalのドキュメント(英語):Introduction | Crystal Programming Language

他のサイトでも指摘されていることですが、あくまでもRuby風なのであって
Rubyのコーディングが同じように使用できるわけではないです。

というわけで、今回はRubyをCrystalに置き換えるとこんなエラーがよく出る
というのを紹介していきます。

Crystalに変更する際に起こるエラーは以下のようなものが存在します。

unterminated char literal, use double quotes for strings

String型にはダブルクオテーションを使用しなさい。というエラー

a = 'hello world!'

ではなく

a = "hello world!"

としなくてはいけません。

for empty arrays use '[] of ElementType'

配列型を使用する場合は配列に入る値の型を指定しなさい。というエラー。

arr = []

ではなく

arr = [] of String

のように記載しなくてはなりません。
Array | Crystal Programming Language

expecting token 'CONST', not 'xxxx'

aliasを使用した際にこのようなエラーが発生します。実質的にRubyのようなaliasの使い方はできないようです。
alias | Crystal Programming Language
aliasやalias_methodなどはRubyと動きが異なるため修正が必要です。
どのように修正が必要かは場合によって変わってきます。

unexpected token: NEWLINE
    private

rubyではprivateを書いた後の関数はすべてprivate関数になりますが、Crystalでは違います。
privateやprotectedの関数にしたい場合はすべてをprivate,protectedと記載する必要があります。

private
  def hoge
     puts "hoge!"
  end
  
  def piyo
     puts "piyo!"
  end

ではなく

  private def hoge
     puts "hoge!"
  end
  
  private def piyo
     puts "piyo!"
  end

としなくてはいけません。

undefined method 'attr_accessor'
undefined method 'attr_reader'
undefined method 'attr_writer'

Crystalのドキュメントにはこのように記述されています。

We prefer getter, setter and property over attr_reader, attr_writer and attr_accessor

つまり
attr_reader, attire_writer, attir_accessorの代わりに getter, setter, property 使ってねということらしいです。

あくまでもRuby風だというのは使っていくとつくづく実感していきます。
えっこれないの!?とかは結構あります。

できれば今後も成長していってもらいたい言語ですので記事を書いていきたいとおもいます。

というわけでしばらくはCrystalについての記事を記載していきます。

なにか、間違いなどありましたらご指摘いただけるとありがたいです。

Javascriptでカラーピッカーを作りました。(BeehivePicker)

必要があったのでJavascript
BeehivePickerというカラーピッカーを作りました。

https://github.com/tebakane/images_for_git/raw/master/images/beehive_picker_screen_shot.png

ライブラリは下記のGitHubにあります。
tebakane/BeehivePicker · GitHub

JSColorなどのライブラリがすでに存在するカラーピッカーなのですが
六角形(蜂の巣型)のカラーピッカーが必要だったので作りました。

使い方はbeehive_picker.jsを読み込んで下記のように使用します。

var div = document.getElementById('main');
Beehive.Picker(div);
div.addEventListener('click', function(e){
  var color = Beehive.getColorCode(e.target);
  if(!color){ console.log('it is not beehive picker color elemnt.'); }
  console.log(color);
});

デモは下記サイト
https://tebakane.github.io/BeehivePicker/sample.html


よかったら使ってみてください。

PostgreSQLの日付操作

前回
Oracleの日付操作 - 鶏頭のプログラム
の記事でOracleの日付操作について記載しました。

今回はPostgreSQLの日付操作について記載します。

SELECT current_timestamp;
SELECT now();

今日

SELECT current_date;

明日

SELECT current_timestamp + '1 day';
SELECT now() + '1 day';
SELECT current_date + 1;

昨日

SELECT current_timestamp + '-1 day';
SELECT now() + '-1 day';
SELECT current_date - 1;

ひと月後

SELECT current_timestamp + '1 month';
SELECT now() + '1 month';

ひと月前

SELECT current_timestamp + '-1 month';
SELECT now() + '-1 month';

一年後

SELECT current_timestamp + '1 year';
SELECT now() + '1 year';

一年前

SELECT current_timestamp + '-1 year';
SELECT now() + '-1 year';

週始まり

SELECT DATE_TRUNC('week', current_timestamp);
SELECT DATE_TRUNC('week', now());

週終わり

SELECT DATE_TRUNC('week', current_timestamp + '1 week') + '-1 day';
SELECT DATE_TRUNC('week', now() + '1 week') + '-1 day';
SELECT DATE_TRUNC('week', current_timestamp + '1 week') + '-1 second';
SELECT DATE_TRUNC('week', now() + '1 week') + '-1 second';

月初

SELECT DATE_TRUNC('month', current_timestamp);
SELECT DATE_TRUNC('month', now());

月末(来月月初の一日前)

SELECT DATE_TRUNC('month', current_timestamp + '1 month') + '-1 day';
SELECT DATE_TRUNC('month', now() + '1 month') + '-1 day';
SELECT DATE_TRUNC('month', current_timestamp + '1 month') + '-1 second';
SELECT DATE_TRUNC('month', now() + '1 month') + '-1 second';

こんな感じでしょうか。

CentOSでFAT32お外付けハードディスクをマウントする

わすれそうなのでメモとして書きます。
下記サイトを参考にしました。

homepage3.nifty.com


ルートユーザーに変更(sudoコマンドでも可)し、vfatとしてマウントするだけです。

su -

マウント先ディレクトリ作成
mkdir mount
そのディレクトリにマウント
mount -t vfat /dev/sdb1 /root/mount -o umask=000

ちなみに外付けハードディスクのファイルシステムを確認するには
fdiskコマンドを使用します。

すると結果的に下記のように表示されるので

f:id:iteba:20150501103247p:plain

赤で囲った部分を確認するとわかります。

Oracleの日付操作

基本的に家ではPostgreSQLを使用しているのですが
仕事ではいろんなデータベースを使用します。

日付操作がかなり必要になったので記録がてら記載します。


月初

SELECT trunc(SYSDATE, 'MM') 月初 FROM DUAL

月末

SELECT LAST_DAY(SYSDATE) 月末 FROM DUAL

1日後

SELECT SYSDATE + 1 明日 FROM DUAL


1日前

SELECT SYSDATE - 1 昨日 FROM DUAL

1ヶ月後

SELECT add_months(SYSDATE, 1) ひと月後 FROM DUAL

一ヶ月前

SELECT add_months(SYSDATE, -1) ひと月前 FROM DUAL

1年後  

SELECT ADD_MONTHS(SYSDATE,12) 一年後 FROM DUAL

1年前

SELECT ADD_MONTHS(SYSDATE,-12) 一年前 FROM DUAL

追記-----------------------------------------------

週のあたま

SELECT TRUNC(SYSDATE, 'DAY') 今週初 FROM DUAL

週末

SELECT TRUNC(SYSDATE, 'DAY') + 6 今週末 FROM DUAL


ちなみにOracleでは週のはじまりは日曜日のようです。