ホーム ブログ ページ 20

AWS + Nginx + UnicornでRailsアプリを公開してみる

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめに

今ならAWSの諸機能が、特定条件下なら1年無料で使えるとのことだったので、試しにRailsアプリをAWS上で作成・公開出来るようにしてみました。

以下のサイトなどを参考にしています。
(デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで
【AWS】Ruby on Rails + Nginx + Unicorn + MySQL 環境構築

Cloud9で環境を構築する。

Cloud9とは、AWS上で利用できるクラウドIDEです。
AWSコンソールのCloud9から、環境を構築できます。

EC2インスタンスは、t2.microタイプであれば無料枠の範囲で利用できるので、こちらを選択します

構築が終わると、cloud9のコンソールが開きます。

rubyとrailsはインストールされているようなので、今回はこのままアプリを作成します。

$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
$ rails -v
Rails 5.2.0

# アプリの作成
$ rails new test-app
$ rails g scaffold user

# マイグレートとアセットプリコンパイル
$ rake db:migrate RAILS_ENV=production
$ rake assets:precompile

Unicornの導入と設定

Gemファイルに追記してUnicornを使えるようにします。

# Gemfile 追記
group :production, :staging do
    gem 'unicorn'
end

# インストール
$ bundle install

config配下に、unicornの設定ファイル(unicorn.rb)を作成・編集します。

  #  unicron.rb
  # set lets
  $worker  = 2
  $timeout = 30
  $app_dir = "/home/ec2-user/environment/test-app/" #アプリの場所
  $listen  = File.expand_path 'tmp/sockets/.unicorn.sock', $app_dir
  $pid     = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
  $std_log = File.expand_path 'log/unicorn.log', $app_dir

  # set config
  worker_processes  $worker
  working_directory $app_dir
  stderr_path $std_log
  stdout_path $std_log
  timeout $timeout
  listen  $listen
  pid $pid

  # loading booster
  preload_app true

  # before starting processes
  before_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
    old_pid = "#{server.config[:pid]}.oldbin"
    if old_pid != server.pid
      begin
        Process.kill "QUIT", File.read(old_pid).to_i
      rescue Errno::ENOENT, Errno::ESRCH
      end
    end
  end

  # after finishing processes
  after_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
  end

Nginxの導入と設定

# Nginxの導入
$ sudo yum install nginx
-- 省略 --
Complete!

# 設定ファイルの書き換え
$ sudo vi /etc/nginx/nginx.conf

pid "/var/run/nginx.pid";
events {
  worker_connections 2048;
}

http {
  upstream unicorn {
    server unix:/home/ec2-user/environment/test-app/tmp/sockets/.unicorn.sock;
  }
  server {
    listen 80;
    server_name XXX.XXX.XXX.XXX; ←EC2インスタンスに割り当てられたIP
    root /home/ec2-user/environment/test-app/;
    error_log /home/ec2-user/environment/test-app/log/nginx.log;
    include /etc/nginx/mime.types;
    location / {
      if (-f $request_filename) { break; }
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_pass http://unicorn;
    }
  }
}

unicornとnginxの起動

NginxとUnicornを起動して、webページが閲覧出来るか確認してみます。

 # unicornの起動
$ bundle exec unicorn_rails -E production -c config/unicorn.rb -D
 # 起動確認
$ ps aux | grep unicorn

#nginxの起動
$ sudo service nginx start
#起動確認
$ ps aux | grep nginx

起動後、EC2インスタンスのIPアドレスにアクセスしたところ無事繋がりました。
(なにもない簡素なページですが。。。)

終わりに

AWSを利用して、railsで作成したアプリをweb公開できました。
NginxやUnicornについて理解がまだ浅いので、どんな設定が出来るのかなど理解を深めていきたいと思います。

【Rails】巨大なテーブル同士をjoinせずに検索【速度改善】

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

巨大なテーブル同士をjoinしてから検索すると遅くなるのでjoinせずに検索する方法を記述します。

例として下記のようなテーブル関連とします。

Post ー* TagPost ー* Tag
 |
 *
Comment

# 投稿
class Post < ActiveRecord::Base
  has_many :comments
  has_many :post_tags
  has_many :tags, though: :post_tags
end

# 中間テーブル
class PostTag< ActiveRecord::Base
  belongs_to :post
  belongs_to :tag
end

# タグ
class Tag < ActiveRecord::Base
  has_many :post_tags
  has_many :posts, though: :post_tags
end

# コメント
class Comment < ActiveRecord::Base
  belongs_to :post
end

上記の状態でコメントとタグのタイトルに「あ」という文字が入っている投稿を取得したい場合はテーブルをjoinして検索すると思います。

Post.joins(:comments, :tags).where(['comments.title LIKE ? AND tags.title LIKE ?', '%あ%', '%あ%' ])

ですががレコード数がそれぞれ数十万件以上だった場合とてもjoinしていられません。かなり遅くなるかと思います。そこで

それぞれのテーブルでpost_idを取得してそれをもとにPostを取得する

# コメントのpost_id取得
comment_post_ids = Comment.where(['title LIKE ?',  '%あ%']).pluck(:post_id)

# タグのid取得
tag_ids = Tag.where(['title LIKE ?',  '%あ%']).pluck(:id)

# タグのpost_id取得
tag_post_ids = PostTag.where(tag_id: tag_ids).pluck(:post_ids)

# 取得したpost_idが一致しているものを取得
post_ids = comment_post_ids & tag_post_ids

# 投稿を検索!
posts = Post.where(id: post_ids)

ポイント

  • pluckを使う
  • 取得したidたちで「&アンド」(どちらかに入っていればいい場合「|オア」)を取る

SQLを複数回実行しますが巨大なテーブル同士をjoinするよりは早くなることがあります。

ActiveRecordのwhereの挙動メモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ActiveRecordのwhereの挙動が同じだったり違ったりするのでメモ

例として使うテーブル

# 投稿
class Post < ActiveRecord::Base
  has_many :comments
end


# コメント
class Comment < ActiveRecord::Base
  belongs_to :post
end

1.whereにhash

Post.where(title: 'タイトル').to_sql
SELECT posts.* FROM posts WHERE posts.name = 'タイトル'  ORDER BY posts.id ASC

default_scopeがつく

2.whereにArray

Post.where(['title = ?', 'タイトル']).to_sql
SELECT posts.* FROM posts WHERE (name = 'タイトル')  ORDER BY posts.id ASC

whereの条件にテーブル名がつかない。()がつく。

3.Arrayの部分にテーブル名を入れる

Post.where(['posts.title = ?', 'タイトル']).to_sql
SELECT posts.* FROM posts WHERE (posts.name = 'タイトル')  ORDER BY posts.id ASC

テーブル名がつく。()がつく。

4.whereに空配列

Post.where([]).to_sql
SELECT posts.* FROM posts ORDER BY posts.id ASC

where条件なし。全件取得。default_scopeがつく。

5.whereに空配列

Post.where([[]]).to_sql
SELECT posts.* FROM posts WHERE () ORDER BY posts.id ASC

全件取得。where ()がつく。

6.whereにString

Post.where("posts.title = 'タイトル'").to_sql
SELECT posts.* FROM posts WHERE (posts.name = 'タイトル')  ORDER BY posts.id ASC

Arrayのときとかわらない。

7.whereに空文字

Post.where('').to_sql
SELECT posts.* FROM posts  ORDER BY posts.id ASC

where条件なし。全件取得。default_scopeがつく。

8.whereにtrue

Post.where(true).to_sql
RuntimeError: unsupported: TrueClass

例外。

9.whereに’true’

Post.where('true').to_sql
SELECT posts.* FROM posts WHERE (true)  ORDER BY posts.id ASC

全件取得。

10.whereに’false’

Post.where('false').to_sql
SELECT posts.* FROM posts WHERE (false)  ORDER BY posts.id ASC

0件。

11.joinしてwhereにhash

Post.joins(:comments).where(title: 'タイトル', comments: {title: 'コメントのタイトル'}).to_sql
SELECT posts.* FROM posts INNER JOIN comments ON comments.color_id = posts.id WHERE posts.title = 'タイトル' AND comments.title = 'コメントのタイトル'  ORDER BY posts.id ASC

Postのdefault_scopeがつく。

12.joinしてmerge

Post.joins(:comments).where(title: 'タイトル').merge(Comment.where(title: 'コメントのタイトル')).to_sql
SELECT posts.* FROM posts INNER JOIN comments ON comments.color_id = posts.id WHERE posts.title = 'タイトル' AND comments.title = 'コメントのタイトル'  ORDER BY posts.id ASC, comments.id ASC

PostとCommentのdefault_scopeつく。

[AWS] LambdaでOpenCVを使用

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Lambda on PythonでOpenCVライブラリを使う

AWS S3(以下、S3)に画像ファイルをアップロードした際、
AWS Lambda(以下、Lambda)で画像加工を行う、というのは
よく使われるケースの一つかと思います。

そこで、Lambda on Python 2.7でOpenCVライブラリを使用するための手順について、ご紹介したいと思います。

ライブラリのimport

[AWS] Fargateの使用上の注意点

0

Information

この記事はアピリッツの技術ブログ「あぴらぼ式」から移行した記事です。情報が古い可能性がありますのでご注意ください。

AWS Fargateって?

AWS Fargate(以下Fargate)は、
AWSが提供するコンテナ実行サービスであるElastic Container Service (以下ECS)のサービスの一種です。

バージニア北部のリージョンでのみ提供されていたサービスですが、
ついに、2018年07月東京リージョンでも提供が開始されました!!

既存のECSの仕組みが、ユーザが管理するEC2のクラスタの上でコンテナが起動されるのに対し、
FargateはEC2の管理をする必要がなく、コンテナが使用するvCPU、メモリを指定するだけでコンテナを実行できます。

冒頭でECSのサービスの一種です、という言い方をしましたが、
基本的には、ECSの仕組みと同じように動作します。

おすすめのAfterEffects無料エフェクトプラグイン紹介

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

セイバープラグイン、ライトセイバーのようなエフェクト他パチンコとかによくあるオーラ系の演出で使われるエフェクトが簡単に作れます
https://www.flashbackj.com/video_copilot/saber/

Color Vibrance、真っ白や真っ黒な画像でも色相や彩度を自在に補正かけることができます。
https://www.flashbackj.com/video_copilot/free_plugin/

サンプルとしてカグヅチさんに燃えていただきました
enter image description here

ざっくりですが手順としましては
1AfterEffectsにエフェクトつけたい画像を読み込む
2レイヤー→オートトレースでキャラとかエフェクトをつけたい物の型のパスを取る
3オートトレースしたレイヤーにエフェクトからセイバーを選択。今回はカグヅチなので火をベースにするためPresetはInfernoを元に適当に数値いじります(この辺は個人差あるので適当にいじってもらった方が楽しいかもです)
Customize Coreの項目にあるCore typeをLayer Maskにするとエフェクトがトレースしたパスに沿ってオーラをまとった感じになります

そのままだとリアルなエフェクトになるのでキャラの雰囲気に合わせて
ポスタリゼーション、ブラー(詳細)、カートゥーンのエフェクトを入れていい感じに調整したら
VC Color Vibranceで好みの色味に調整します。

これは別にサンプルなんで適当にざっくりやっちゃってますがもう少し細かく数値設定してあげればもう少し面白く仕上がるかなと思います。

ちなみにセイバープラグインはAfterEffectsの最新バージョンだと対応していないため要注意です

Samba 設定メモ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

VirtualBox 上で CentOS や Ubuntu を起動させ、 Samba でファイル共有

Centos6の場合

sudo yum install -y samba
sudo chmod 755 /home/$USER
sudo smbpasswd -a $USER
sudo cp -a /etc/samba/smb.conf /etc/samba/smb.conf.org
sudo vi /etc/samba/smb.conf # 編集方法は以下参照
sudo /etc/rc.d/init.d/smb start
sudo /etc/rc.d/init.d/nmb start
sudo chkconfig smb on
sudo chkconfig nmb on
sudo setsebool -P samba_export_all_rw 1
sudo /etc/rc.d/init.d/iptables stop
sudo chkconfig iptables off
sudo chkconfig ip6tables off

編集方法

  • 57行目の下に追加
     58 ### START ###
     59         unix charset = UTF-8
     60         dos charset = CP932
     61         display charset = UTF-8
     62 ### END ###
  • 79行目を変更
     79 ### START ###
     80 #       workgroup = MYGROUP
     81         workgroup = WORKGROUP
     82 ### END ###
  • 88行目の下に追加
     89 ### START ###
     90         hosts allow = 127.0.0.1 10. 172.16. 192.168.
     91 ### END ###
  • 232行目を変更
    232 ### START ###
    233 #       load printers = yes
    234         load printers = no
    235         disable spoolss = yes
    236 ### END ###
  • 266行目の下に追加
    267 ### START ###
    268         create mask = 644
    269         directory mask = 755
    270 ### END ###

CentOS7 の場合

sudo yum install -y samba
sudo chmod 755 /home/$USER
sudo smbpasswd -a $USER
sudo cp -a /etc/samba/smb.conf /etc/samba/smb.conf.org
sudo cp /etc/samba/smb.conf.example /etc/samba/smb.conf
sudo vi /etc/samba/smb.conf       # 編集方法は以下参照
sudo systemctl enable smb.service
sudo systemctl enable nmb.service
sudo systemctl restart smb.service
sudo systemctl restart nmb.service
sudo setsebool -P samba_export_all_rw 1
sudo systemctl stop firewalld

編集方法

差分が以下のようになるよう修正する

[admin@localhost ~]$ diff -uprN /etc/samba/smb.conf.example /etc/samba/smb.conf
--- /etc/samba/smb.conf.example 2017-11-28 01:21:52.000000000 +0900
+++ /etc/samba/smb.conf 2018-05-02 20:50:00.157765018 +0900
@@ -60,6 +60,9 @@
 #======================= Global Settings =====================================

 [global]
+unix charset = UTF-8
+dos charset = CP932
+display charset = UTF-8

 # ----------------------- Network-Related Options -------------------------
 #
@@ -81,13 +84,13 @@
 # hosts deny = the hosts not allowed to connect. This option can also be used on
 # a per-share basis.
 #
-       workgroup = MYGROUP
+       workgroup = WORKGROUP
        server string = Samba Server Version %v

 ;      netbios name = MYSERVER

 ;      interfaces = lo eth0 192.168.12.2/24 192.168.13.2/24
-;      hosts allow = 127. 192.168.12. 192.168.13.
+       hosts allow = 127.0.0.1 10. 172.16. 192.168.

 # --------------------------- Logging Options -----------------------------
 #
@@ -244,7 +247,8 @@
 # printcap name = used to specify an alternative printcap file.
 #

-       load printers = yes
+       load printers = no
+       disable spoolss = yes
        cups options = raw

 ;      printcap name = /etc/printcap
@@ -278,6 +282,8 @@
        writable = yes
 ;      valid users = %S
 ;      valid users = MYDOMAIN\%S
+       create mask = 644
+       directory mask = 755

 [printers]
        comment = All Printers

Ubuntu の場合

sudo apt-get install -y samba
sudo pdbedit -a $USER
sudo cp -a /etc/samba/smb.conf /etc/samba/smb.conf.org
sudo vi /etc/samba/smb.conf        # 以下参照
sudo systemctl restart smbd
sudo systemctl restart nmbd

編集方法

差分が以下のようになるよう修正する

$ diff -uprN /etc/samba/smb.conf.org /etc/samba/smb.conf
--- /etc/samba/smb.conf.org     2018-05-02 18:16:25.567600455 +0900
+++ /etc/samba/smb.conf 2018-05-02 18:20:40.762445925 +0900
@@ -190,13 +190,13 @@
 # Un-comment the following (and tweak the other settings below to suit)
 # to enable the default home directory shares. This will share each
 # user's home directory as \\server\username
-;[homes]
-;   comment = Home Directories
-;   browseable = no
+[homes]
+   comment = Home Directories
+   browseable = no

 # By default, the home directories are exported read-only. Change the
 # next parameter to 'no' if you want to be able to write to them.
-;   read only = yes
+   read only = no

 # File creation mask is set to 0700 for security reasons. If you want to
 # create files with group=rw permissions, set next parameter to 0775.
@@ -211,7 +211,7 @@
 # Un-comment the following parameter to make sure that only "username"
 # can connect to \\server\username
 # This might need tweaking when using external authentication schemes
-;   valid users = %S
+   valid users = %S

 # Un-comment the following and create the netlogon directory for Domain Logons
 # (you need to configure Samba to act as a domain controller too.)

ファイアウォールのポート開放

sudo ufw allow 137
sudo ufw allow 138
sudo ufw allow 139
sudo ufw allow 445

すべてのポートを空ける場合は以下

sudo ufw default ALLOW

Ubuntuからアクセスする方法(Ubuntuがクライアントの場合)

sudo apt-get install -y cifs-utils
sudo mkdir /mnt/XXX

※「XXX」は任意

マウント

sudo mount.cifs //AAA.AAA.AAA.AAA/BBB /mnt/XXX/ -o username=BBB,uid=$(id -u),gid=$(id -g)

AAA : サーバIP
BBB : サーバ側のユーザ名

アンマウント

sudo umount /mnt/XXX

花粉症を軽減する方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。


今年に入って花粉症を発症し、症状がひどくストレスに満ちた生活を送っているBe82Mです。
集中力が散漫になりがちで困っているので、今回軽減するために必要なことをまとめてみました。
 

目次

  • 規則正しい生活を送る
  • ストレスを発散する
  • アルコールを控える
  • 喫煙を控える

規則正しい生活を送る

どの病気にも言えることですが、睡眠をしっかりとって免疫力を高めることが大切です。
また、帰ってきたときに服を軽く叩くなど極力家に花粉を持ち込まないようにし、こまめに部屋の掃除を行いましょう。
外出した日は特に体に付着した花粉を洗い流すため、朝シャンは避けて寝る前に入る方がいいそうです。
外出の必要がない日は無闇に外出せず、花粉を必要以上に吸引しないように心がけましょう。
 

ストレスを発散する

ストレスも免疫を低めてしまう原因になっているので、極力ストレスは趣味や適度な運動を行うことで発散するようにしましょう。
花粉症の症状がひどくなると、なかなか寝付けなかったり、普段の生活でも花粉症の症状だけで大きなストレスになってしまい、悪循環になってしまいます。
症状はすぐに軽減できないので、他のストレスとなる要因を絶ったり、どうしようもない場合は発散する時間を作るように心がけましょう。
 

アルコールを控える

アルコールは血管を拡張させるため、目の充血や鼻づまりを引き起こしてしまう要因となるようです。
また、粘膜を乾燥させてしまうため体内への花粉の侵入を防ぎにくくなってしまいます。
加湿器などを使って空気の乾燥を防ぐことで粘膜の乾燥も防ぐことは可能ですが、水分補給を行うなど内部からも水分を補うように心がけましょう。
 

喫煙を控える

煙が鼻の粘膜を刺激することで、鼻づまりなど症状を悪化させてしまうようです。
そのため喫煙者の近くにいるだけでも症状悪化の原因となってしまいます。
しかし、タバコに含まれるニコチンは血管を収縮させる作用があり、症状が軽減される要素も含んでいます。
粘膜の乾燥を防ぎ、煙によって症状を引き起こさないように対策しつつ、周囲に気を遣って喫煙をすれば特に問題はないかもしれません。
 

余談

先々月に奥多摩町に遊びに行ったことを激しく後悔しています。とても楽しかったですが、あれから本当に症状がひどくなり、その後数日まで症状がひどい状態が続きました。
興味本位で1平方センチメートルあたりの花粉飛散量を調べましたが、23区内の平均が40〜50個なのに対し、奥多摩町は6000個を超えているそうです…。
確かに辺りは靄のようになっているし、1時間足らずで車が緑色になってしまうくらい目に見えて飛散量が違いました。
必要以上に対策したにも関わらず、目は真っ赤で涙がボロボロ出るし、くしゃみは止まらない…普段よりひどい症状に苦しめられる結果になりました。
景観はいいし、車やバイクで走るにもトレッキングにも最適。また、わらび餅が美味しいことで有名で魅力多い町ですが、花粉症を発症してしまったり、既に発症している人は症状悪化に繋がってしまいます。
観光に行こうと思っていた方は時期をずらして行くことをおすすめします。

メモ化トラップ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢🍢

 みなさーん! 快適Railsライフ送ってますかー!!?? 私は快適ではありません……。先日も訳の分からないエラーに引っかかって四苦八苦しました……。
 メモ化という事柄に関してです。

メモ化とは

 メモ化って便利だよなー。マスタを一々データベースから参照せずに取ってこれるから高速に取ってこれるんだぜ! 
 使いやすいgemもあるし。

/app/models/oden_master.rb

class OdenMaster < ActiveRecord::Base
  extend Memoist

  class << self
    def oden_data_memo(oden_code)
      find_by(code: oden_code)
    end
    memoize :oden_data_memo
  end
end

こんな感じにしちゃえば、同じ名前のおでんマスタは1度参照して来てしまえばキャッシュされるからもうSQLを呼ばずに取って来れる!

発端と実装

某日:
くらいあんと「おでん情報にユーザーの好みくっつけて送ってくれない?」
ぼく「わかりました!」
ぼく「うーん、どうしようかな。インスタンスに属性付けちゃえば楽だな」

/app/models/oden_master.rb

class OdenMaster < ActiveRecord::Base
  extend Memoist

  attr_accessor :preference_data

  class << self
    def oden_data_memo(oden_code)
      find_by(code: oden_code)
    end
    memoize :oden_data_memo
  end

  def set_user_preference_data(user_data)
    self.preference_data = user_data
  end
end

で、コントローラはこんな感じにして、後はviewをいい感じに作れば完了!(結構簡略化してます)

app/controllers/oden_controller.rb

  def current_oden
    user = User.find_by(code: params[:user_code])
    raise InvalidUser unless user
    oden_code = params[:oden_code]
    @oden_master = OdenMaster.oden_data_memo(oden_code)
    raise InvalidOden unless oden_master

    user_oden_data = user.oden_preferences.find_by(oden_code: oden_code)
    @oden_master.set_user_preference_data(user_oden_data) if user_oden_data
  end
end

テストも簡単に作って、通ったし問題無いな! メモ化して一度呼んできたマスタはもう取ってきてあるし、大丈夫!
コミットしてマージしてプッシュして開発環境にデプロイして(要するにクライアントが開発環境で試せる環境を作る)。
くらいあんと「大丈夫そうですね」
ぼく「お仕事完了!」
……しかしこのコードには致命的なミスがあるのがまだ、この時点では分からなかった。

発覚

数日後
てすたー「なんか別のユーザーのデータ入ってきてるよ」
ぼく「えっ」
ぼく「なんでだろう……。コンソール上で実際に動かしても何の問題も無いし……。うーん、うーん……」
てすたー「まだ、このおでんマスタに対するおでんデータ作ってないのに、入っちゃってるんだよね。それに私、こんなに辛子を大根に付けないんですよ」
ぼく「そうですか……。何でだろう。因みに私はたっぷり付けてゲホゲホ言いながら食べるのが好きです。」
てすたー「変態かよ。まあ、おでんデータ入れればちゃんと自分の入ってくるんだけど」
ぼく「むせる感覚が最高なんですよ。なんでこんな短いコードでそんな事が起きるんだろうなぁ……。調べてみます」

 多分悩んだのは30分~1時間位だった。
 問題は、memoizeをちゃんと読み込んでいなかった事にありました。
 以下が、memoizeのソースになります。

  def memoize(*method_names)
    if method_names.last.is_a?(Hash)
      identifier = method_names.pop[:identifier]
    end

    method_names.each do |method_name|
      unmemoized_method = Memoist.unmemoized_method_for(method_name, identifier)
      memoized_ivar = Memoist.memoized_ivar_for(method_name, identifier)

      Memoist.memoist_eval(self) do
        include InstanceMethods

        if method_defined?(unmemoized_method)
          warn "Already memoized #{method_name}"
          return
        end
        alias_method unmemoized_method, method_name

        if instance_method(method_name).arity == 0

          # define a method like this;

          # def mime_type(reload=true)
          #   skip_cache = reload || !instance_variable_defined?("@_memoized_mime_type")
          #   set_cache = skip_cache && !frozen?
          #
          #   if skip_cache
          #     value = _unmemoized_mime_type
          #   else
          #     value = @_memoized_mime_type
          #   end
          #
          #   if set_cache
          #     @_memoized_mime_type = value
          #   end
          #
          #   value
          # end

          module_eval <<-EOS, __FILE__, __LINE__ + 1
            def #{method_name}(reload = false)
              skip_cache = reload || !instance_variable_defined?("#{memoized_ivar}")
              set_cache = skip_cache && !frozen?

              if skip_cache
                value = #{unmemoized_method}
              else
                value = #{memoized_ivar}
              end

              if set_cache
                #{memoized_ivar} = value
              end

              value
            end
          EOS
        else

          # define a method like this;

          # def mime_type(*args)
          #   reload = Memoist.extract_reload!(method(:_unmemoized_mime_type), args)
          #
          #   skip_cache = reload || !memoized_with_args?(:mime_type, args)
          #   set_cache = skip_cache && !frozen
          #
          #   if skip_cache
          #     value = _unmemoized_mime_type(*args)
          #   else
          #     value = @_memoized_mime_type[args]
          #   end
          #
          #   if set_cache
          #     @_memoized_mime_type ||= {}
          #     @_memoized_mime_type[args] = value
          #   end
          #
          #   value
          # end

          module_eval <<-EOS, __FILE__, __LINE__ + 1
            def #{method_name}(*args)
              reload = Memoist.extract_reload!(method(#{unmemoized_method.inspect}), args)

              skip_cache = reload || !(instance_variable_defined?(#{memoized_ivar.inspect}) && #{memoized_ivar} && #{memoized_ivar}.has_key?(args))
              set_cache = skip_cache && !frozen?

              if skip_cache
                value = #{unmemoized_method}(*args)
              else
                value = #{memoized_ivar}[args]
              end

              if set_cache
                #{memoized_ivar} ||= {}
                #{memoized_ivar}[args] = value
              end

              value
            end
          EOS
        end

        if private_method_defined?(unmemoized_method)
          private method_name
        elsif protected_method_defined?(unmemoized_method)
          protected method_name
        end
      end
    end
    # return a chainable method_name symbol if we can
    method_names.length == 1 ? method_names.first : method_names
  end

 まあ、コードの解説は抜きにして、端的に言えば、メモ化で参照されるデータは単一のものである、という事です。
 その単一のものに対して破壊的変更をしてしまえば、そのメモ化で参照されるデータにも勿論影響が及びます。

 上記のコードだと、

ユーザーA: おでんコードXに対するユーザーデータを持つ
ユーザーB: おでんコードXに対するユーザーデータは持たない

 と言う条件の下で、

1. ユーザーAがおでんコードXに対する情報を取得
メモ化されたおでんコードXのマスタの属性にデータが入る。

2. ユーザーBがおでんコードXに対する情報を取得
メモ化されたおでんコードXのマスタの属性はユーザーAのものが入ったままデータが送られてしまう。

 と言う事が起きてしまう訳です。カラムに変更を掛けてしまっても同じ事が起こります。

解決

 まあ、策としては色々あります。
・メモ化して取ってきてくる時に属性を初期化する
・データが無くてもnilなどを明示的に入れる
・属性を使わない。メモ化したデータを弄る事をそもそもしないように心掛ける
 等々。
 自分は一番上の、メモ化して取ってきてくる時に属性を初期化する、を選びました。下のような感じにメソッドを作ったりしてそれを取ってくるようにして。

def attr_initialized_oden_data_memo(oden_code)
  oden_data = oden_data_memo(oden_code)
  oden_data.preference_data = nil
  oden_data
end

 理由としては、まあ実装上の設計の問題みたいな感じですが。
 そこ辺りは設計と相談にもなってきます。

 それではより良いおでんライフを。

Unityのシェーダーについて

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

Unityのシェーダーについて自分で調べたことをまとめました。

はじめに

どうもmotsuka です。
今回はシェーダーを書いてみたくなったのでいろいろと調べてみたことをまとめてみたいと思います。

シェーダーとは

シェーダーとはシェーディング処理(陰影処理)を行うプログラムのことで、オブジェクトの頂点や色を変えるプログラムのことを指します。ポリゴンやテクスチャ等の画像をどのように画面に表示するかを決めるプログラムです。

またUnityでは3つのシェーダーがあり、

  • 固定関数シェーダー
  • サーフェイスシェーダー
  • 頂点フラグメントシェーダー

Unityでシェーダーを書くときこれらを使い分けて書く必要があります。
これらを簡単に説明すると

  • 固定関数シェーダー
    これはプログラマブルシェーダーをサポートしていない古いハードウェア用のシェーダーです。またこのシェーダーは後述のPass句のみからなるシェーダになります。
  • サーフェイスシェーダー
    影やライティングを扱うときに書くシェーダーです。
  • 頂点フラグメントシェーダー
    オブジェクトの頂点を変更したあとに色を変更することのできるシェーダーです。子のシェーダーでは結構複雑なエフェクトなどを表現するときに使用します。

これらUnityで動くすべてのシェーダーでShaderLabという書式で書かれます。
これらの項目はまとめにURLが書いてあるので詳しく読みたい方はそちらをご覧ください。

サンプルコード

では、簡単なシェーダーを書いてみましょう

今回は簡単な例として画面上に置かれた立方体の色を変えるプログラムを書いていきたいと思います。

まず、プロジェクト内で右クリックをして Create -> Shader -> Standard Surface Shaderをクリックしてシェーダーを作ります。
それをテキストエディタで開いてみましょう。

Shader "Custom/Test" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
       CGPROGRAM
       #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0
        sampler2D _MainTex;
        struct Input {
            float2 uv_MainTex;
        };
        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)
        void surf (Input IN, inout SurfaceOutputStandard o) {
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse" }

上のようなソースができたと思います。
上から読んでいきましょう
大きく分けて二つの枠に分けることができます。

  • Properties
    ここにはUnity側からシェーダーに渡したいものを記述します。
    簡単に言うと変数宣言の場所と思ってください。
    Unity側からのデータを任意の名前を付けて使えるようにする場所です。
    このソースでは、色のデータや表面のテクスチャなどのデータを渡しています。
    この項目はインスペクター上に表示され変更することができるものになります。
  • SubShader
    ここには実際にシェーダーの中身を書いていく場所です。
    CGPROGRAMが処理の始まりを示していて、ENDCGが処理の終わりを示しています。
    この句のメインの処理はsurf関数です。
    ここではinputをうけとり様々な処理をしてSurfaceOutputStandardに詰めるという処理になっています。またinputに何が渡ってくるかはその上に書いてあるstructにて記述してあります。

ではこのソースを変えてこのシェーダーがついているオブジェクトの色を変えましょう。

_Color (“Color”, Color) = (1,1,1,1)

の行を下のように書き換えます。

_Color (“Color”, Color) = (1,0,0,1)

に変えて保存したシェーダーからマテリアルをつくって適当なオブジェクトにアタッチしてみてください。
そうすると色が赤色に変わったことが確認できます。

まとめ

書いたことがなかったシェーダーですが、やってみるとあまり難しくなくさっくりとできる印象ですので皆さんもやってみてはいかがでしょうか?ですが、C#とは全く違う書き方や最初はよくわからないパラメータが多く出てくるので最初はきついかもしれませんが、慣れるとすんなり読めるようになるので皆さんもシェーダーを書いてみましょう。
次は文字のアウトラインをシェーダーで書いてみたいですね。余裕があったらまた書きたいと思います。
参考にしたURLを下にのせておくのでそこから読んでもらうと理解がより深まると思います。

Unity Documentation シェーダーマニュアル
https://docs.unity3d.com/ja/current/Manual/ShadersOverview.html

Unity のシェーダの基礎を勉強してみたのでやる気出してまとめてみた
http://tips.hecomi.com/entry/2014/03/16/233943

心くすぐられる物理学ワード

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

アニメやゲーム等、どこかで聞いたことありそうな物理学ワードを、生まれた背景や意味などを添えて集めてみました。意味が分かることで、より世界観を楽しめるようになるのではないでしょうか。

シュレディンガーの猫

 恐らくこの記事で最も有名な物理学ワードです。
 これは、量子力学という分野において、粒子の状態が1つに決まらないことを元にしたパラドックスになります。
 日常的に考えると、物事の状態は必ず一つに決まっていきます。(コインを投げれば表か裏かのどちらかに決まる、など)
 しかし、量子力学の世界では、小さな粒子は複数の状態の重ね合わせで表現され、人間が観測するまで状態が決まりません。これが日常的認識と大きく違っているために、この量子力学を批判する次のような逸話が生まれました。
「Aの状態とBの状態の重ね合わせで表現される粒子があり、Aの状態になると毒ガスが出る箱を作って、猫を閉じ込める。
すると、箱を開けて観測するまで、粒子はAとBの重ね合わせなので、猫もまた生きている状態と死んでいる状態の重ね合わせになってしまう。」
※これは思考実験であり、実際に猫が犠牲にされた実験ではありません。
 これがシュレディンガーの猫と言われるパラドックスです。
 猫の生きている状態と死んでいる状態との重ね合わせという、日常的にあり得ないことが起こってしまう、と批判している文言なのですが、非常に小さい粒子の状態を、猫という大きなものへ影響させるということは、現代の技術でも発展途上のため、この話の真偽はまだ分かりません。

ディラックの海

 これも量子力学の分野の話です。
 ディラックという有名な物理学者が、量子力学の世界での粒子の状態を表す式を導き出しました。しかし、この式ではエネルギーがいくらでもマイナスの状態である粒子が存在しても良いことが分かりました。粒子の性質として、エネルギーが小さい方へ行く性質があるので、これでは実在する全ての粒子がマイナス状態へ落ちていってしまう、と懸念されました。
 これを説明するために、「マイナスの状態はすでに粒子が満員状態になっている」という概念を提唱しました。
 これがディラックの海と呼ばれるものです。これらは、のちに別の理論によって解決され、ディラックの海は不要となってしまいました。

エントロピー

 これは単純に物理学用語です。
 エントロピーは物事の状態の「散らかり具合」を示す量で、物理学だけでなく、情報理論にも用いられている概念です。
 このエントロピーは増える方向(散らかっていく方向)にしか動かない性質があり、エントロピー増大の法則と言われます。
(局所的にはエントロピーは減少することもあり得ます。しかし、全体で見れば増加しています)

マクスウェルの悪魔

 これは物理学だけでなく情報理論にも関わるお話です。
 空気の温度は、空気中の分子の温度の高いモノと低いモノの平均で出来上がっています。そこで、マクスウェルという物理学者は次のような思考実験を考えました。
「仕切りで2つの部屋に分けた箱を用意し、温度の高いモノを右の部屋へ、低いモノを左の部屋へ移すことが出来れば、何も特別なこと(「仕事」と言います)をする必要もなしに部屋の温度を上げたり下げたりできるのではないか。」
 この思考実験は、上述のエントロピー増大則に反するため、注目を浴びました。
 文中の、「熱い分子と冷たい分子を見分ける存在」が、のちにマクスウェルの悪魔と呼ばれるようになりました。
 この問題の解決には、物理学だけでなく情報理論の助けも必要でした。
 この見分けている悪魔が、何の仕事もしていないように見えて実は仕事をしていたのです。この悪魔は粒子状態の情報を取得し、次の粒子を観測するために、前の情報を消去する必要があり、この過程で仕事をしていることが分かったため、結論として熱力学の法則と矛盾しない、ということが分かりました。

enter image description here

ラプラスの悪魔

 物理学というよりは少し哲学的なお話です。
 止まっている物Bに、物Aがぶつかって物Bを吹き飛ばしたとします。この時、物Aと物Bの重さ等の性質が分かっていれば、物Bがどのぐらいの速さで吹き飛んでいったのか計算することが出来ます。
 つまり、物同士がぶつかる前からその先の未来を予言できてしまうわけです。
 これの究極的な主張として、
「現在の、この世の全ての物の状態が分かってしまえば、この先の未来全ての状態が分かってしまうだろう。また、逆に現在より過去の全ての状態も分かってしまうだろう。」
ということを数学者ラプラスが主張しました。のちに、この世全ての状態を知っている存在が、「ラプラスの悪魔」と呼ばれるようになりました。
 これは、この世のすべての出来事は決まっていることなのだ、という決定論的な考えにも見ることが出来ます。
 現代では非常に小さい粒子の挙動は確率で記述されるため、起こるまで分からないという見方がされています。
 一方で、確率変動で世界が分からないのではなく、粒子が取り得る状態の数だけ世界が分岐しているという見方もされています(エヴェレットの多世界解釈)。

終わりに

いかがでしたでしょうか。結構聞いたことがある言葉が多かったのではないでしょうか。
これで今後の創作物にこのようなワードが出てきた時も、にやにやしながら世界に浸ることが出来ますね。

取り込んだ素材を自然に見せる方法

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

はじめに

近年たくさんの素材サイトがありとても便利です。
柄などの素材をイラストに取り入れた際どう見えるのか
柄が浮いてしまったり、線画が素材に負けてしまうのを自然に見せるやり方をご紹介します。

※Photoshopを使用しています。
素材はURLのフリー素材のサイトから使用しています。
・がま口テクスチャ:http://bg-patterns.com/
・柄テクスチャ: http://frame-illust.com/

線画に素材を加えます。
enter image description here
enter image description here
この際に線の色を変えるだけで素材の色味と馴染みやすくなりアイコンのようにシンプルな見た目になります。これをいろいろいじってみます。

影つけ

影のレイヤーを乗算にすることでベースの白と素材にも影をつけます。
そうすることで絵に厚みをつけることができます。
enter image description here
enter image description here

素材の色変え

素材自体の色を変えた場合は全体の配色を同系色で統一させ、
線の色だけでなく影も色を変えます。
影色を調整する際は(彩色・彩度)からバーを動かせば簡単に変更できます。
enter image description here
enter image description here

素材を変形

編集>変形>ワープ
で素材を変形させることで立体感を表現することができます。
enter image description here
柄を複製してチェック柄に変えることもできます。
enter image description here

さいごに

今回はフリー素材を使用し個人的な方法をご紹介しましたが、仕事の場は各現場のルールがあると思いますのでそれに合わせていきましょう。

ボキャブラリーを増やすコツ

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

ボキャブラリーとは何か

ボキャブラリーとは、日本語に訳すと「語彙(ごい)」という意味です。
語彙とは、簡単に言うと「世の中に存在する言葉全て」です。
「ボキャブラリーが乏しい」というのは、「知っている単語」又は「使える単語」が乏しいという意味になる。

【引用】カタカナ語の意味まとめ

ボキャブラリーは自分の意見や考えていることを伝えるために必要になります。
今回はボキャブラリーを増やす方法をご紹介します。

読書

一番わかりやすく手っ取り早い方法です。
最初は自分の興味のあるジャンルからはじめて
徐々に幅を広げていけば
今まで知らなかった言い回しを見つけたり、
間違って覚えていた、使っていた言葉の正しい使い方を確認することができます。
結果としてボキャブラリーは増えているはずです。

インプットするだけでなく、
調べたこと、知ったことをまとめることで
アウトプットもできるとより身に付くのではないでしょうか。

調べる癖をつける

普段、自分の頭の中で考えられることは基本的に
自分が知っている言葉の中で行われています。

知らないことは当然思考には入りません。
知らない分だけ思考に制限がかかってしまうのです。

知らない言葉や気になる言葉を見つけたときはボキャブラリーを増やすチャンス!
すぐに調べましょう!
いまはスマートフォンで簡単に調べることができるのでそこまで手間ではありません。

後回しにすると大抵の場合、調べないままほったらかしになります。

「やばい」禁止

「やばい」という言葉は様々な状況で使えてしまうため
便利である一方、正確な意味が伝わりづらいです。


・このお店、雰囲気やばくない?
・このゲーム、難易度やばい!

良いとも悪いともとれる、その場のテンションなどでなんとなく意味は
推し量れますがあくまで推測に過ぎません。

自分の意見、考えを正確に伝えたい場合は避けるべきでしょう。

まとめ

・読書
・調べる癖をつける
・「やばい」禁止

以上、ボキャブラリーを増やす方法をご紹介しました。
ボキャブラリーを増やしたいと思っている方は意識してみてはいかがでしょうか。

極・メカニカルキーボード生活

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

最近購入したメカニカルキーボードが良い意味で変態的な仕様でしたのでご紹介したいと思います。

フルサイズキーボードとテンキーレスキーボード

フルサイズキーボードとは、テンキーが付いている標準的なキーボードのことで、日本語配列では108キーあります。
横に長いためスペースを取りますが、数字の入力がスムーズに行えるため、表計算ソフト等で数値入力を頻繁に行う人には向いています。

テンキーレスキーボードとは、その名前の通りテンキーがないキーボードのことです。日本語配列では91キーあります。
フルサイズキーボードに比べデスク上でのスペースを削減できるため、自分の好みのポジションに動かしやすいという利点がありますが、数値入力を頻繁に行う方にはあまり向いていません。

40%サイズキーボード

最近私は「Vortex Core」というキーボードを購入し、オフィスで使用しています。
画像検索すると分かりますが、とても小さいキーボードなので持ち運びに便利です。
vortex core – Google 検索
数字キーやファンクションキーは廃され、矢印キーすらなくなっています。
その大きさは248 x 76.2 x 25.5mmというサイズです。iPhone7 Plusのサイズが158.2 x 77.9 x 7.3 mmですので、幅についてはこのキーボードのほうが小さいということが分かります。

ここまで小さいと使いづらくないのか、と皆さんお思いになるでしょうが、その通り使いづらいです。

非常に使いづらいです。

このキーボードには「Fnキー」と「Fn1キー」があり、それらと他のキーの組み合わせで数字を入力したり矢印キーを使うことになります。
慣れればどうということはないと思いますが、慣れるまでに時間がかかります。

ですが、本体はとてもシンプルな作りで持ち運びもしやすいため、Macbookと一緒にオシャレな喫茶店で広げればドヤれるかもしれませんね。
ちなみにこのキーボードはWin版しかないため、Macでご利用いただく場合は各々工夫が必要となります。

おわりに

世の中にはさらに特殊なキーボードもありますが、小ささを求めるとこのキーボードに行きつくのかもしれません。
皆さんもキーボー道を極めていきましょう。

OGPを設定してFacebookシェアで目立たせよう!

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

OGPで画像を設定してシェア時に目立たせる様な対応を行ったのでそれについて記事にします。

はじめに

連続投稿となります。待ちに待ったプロ野球が開幕してテンション高めのむらさきです。
今回はFacebook等SNSでのシェアでたくさんの人の目に留まるように画像やタイトル等を設定するOGPについて書いていきたいと思います。

OGPとは

OGPとはOpen Graph Protocolの略です。FacebookなどのSNSにウェブページの情報を載せる際に必要なタグのことです。
OGPを設定することで下図のようにシェア時に任意の画像やタイトルを入れることができます!
enter image description here
画像を入れることで多くの人の目に留まるようになりたくさんの人に見てもらえる機会が増えるので是非設定しましょう!

OGPの設定方法

OGPは設定したいページのhead内に以下のようなmetaタグを入れることで設定できます。

<meta property="og:locale" content="ja_JP">
<meta property="og:site_name" context="DoRuby">
<meta property="og:title" context="RailsでLoggerを使ってLogローテーション">
<meta property="og:description" context="DoRubyは、株式会社Appirits(アピリッツ)が運営するWeb技術・マーケティング情報発信ブログです。Ruby on Railsを中心に開発現場ならではの実践的な情報を随時掲載していきます。">
<meta property="og:type" context="article">
<meta property="og:url" context="https://doruby.jp/users/ueki/entries/Rails%E3%81%A7Logger%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6Log%E3%83%AD%E3%83%BC%E3%83%86%E3%82%B7%E3%83%A7%E3%83%B3">
<meta property="og:image" context="https://doruby.jp/images/doruby_og.png">

今回はこのように設定しました。
OGPには必須で入れないといけないものが4つあります。

og:title    ページのタイトル
og:type     どんなページなのか(今回は記事のページなのでarticleを設定しました。blogやwebsiteなどもあります。)
og:url      ページのurl
og:image     ページの画像

です。それ以外に書かれているmetaタグは必須ではないですが入れることでより詳しく表示させることができます。

og:description     ページの説明文
og:locale         サポートしている言語
og:site_name       サイトの名前

となっています。自分のページに合わせて設定しましょう!

OGPの確認

OGPが正しく設定されているかを確認するにはfacebook for developersのシェアデバッガーを使用しましょう。
ここに確認したいページのurlを入れることで正しく設定されているかを確認できます。
また、設定してもfacebookのクローラーにクロールされないと設定した画像等には切り替わらないのですが、「もう一度スクレイピング」を押すことですぐに設定した情報を反映させることができます。

おわりに

いかがだったでしょうか。
OGPを設定して画像を変えたのに変わっていない!?と焦りましたが、シェアデバッガーで確認と同時に更新が出来るのでクロールされるのを待つ必要がないのはとてもいいですね。
OGPを正しく設定してたくさんの人の目に留まるサイト作りを目指しましょう!

変数命名:ハンガリアン記法について

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

皆さんはどのように変数名を決めているでしょうか。
命名規則がしっかり決まっているようであればそれに合わせれば良いのでしょうが、
複数人でプログラムしている場合、同じ単語を使っていても違った使い方をされる変数だったりすることがあります。
そんなことが自分自身にもありましたので命名規則の内の一つ、ハンガリアン記法について書いていきます。


ハンガリアン記法とは?


キャメルケース、スネークケースなどの単語と単語のつなげ方を意味するものではなく、
変数の意味や用途をわかやすくするために情報つけて命名するもので、以下の二つのものがあります。

  • アプリケーションハンガリアン
  • システムハンガリアン

アプリケーションハンガリアン


変数名にその変数の情報をつけてぱっと見で間違いを分かりやすくする方式です。
例えば何かの座標を入れる変数名に
positionX
positionY
と命名するのではなく、
absPositionX
relPositionY
といったように絶対座標なのか相対座標なのかといった情報を付け加えるといった感じです。
そうすることによって書かれたコードが間違いであることを分かりやすくします。

Player.posX = absPositionX;
Player.posY = relPositionY;

上記のような代入がされていたら誰でも疑問を抱くと思います。
アプリケーションハンガリアンなんて知らなくても、用途を分かりやすくしようと
変数名をつけるときにこのような形にしている人もいるんではないでしょうか。


システムハンガリアン


ハンガリアン記法といったらこっちのイメージが強いです。
変数名の頭などにその変数の型やスコープなどの情報となる文字をつける方式です。

一般的な例を以下の表にまとめました。

型,スコープなど追加文字使用例
論理型bbEnable
整数型nnCount
浮動小数型ffAngle
文字列ssDescription
ポインタppParent
グローバル変数g_g_pManager
クラスCCManager
クラス内のメンバ変数m_m_nCount

デメリット

  • システムハンガリアンで変数名をつけていた場合、途中から変数の型を変更しようとした場合多くの手間がかかる。
  • 型を変数名につけてしまっているので、変数名の変更忘れなどがあると無駄にソースが分かりにくくなってしまう。
  • 移植性が悪くなる。

おわりに


個人的にシステムハンガリアンに関しては型宣言を必要とするc++やc#においては全く必要がないかと思います。
コンパイル時点でエラーや警告でわかる場合が多いですし。

ですが型宣言を必要としないrubyなどの言語ではシステムハンガリアンで記述してもいいなと思いました。
変数にいろんな型のデータを代入できるがゆえに、何を入れるための変数なのか、何が入っている変数なのか役割をしっかり定義しておいたほうがいいと思います。

17新卒投稿記事ランキング!

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

新卒研修合宿でDoruby月1投稿を決めてから約10ヵ月。 ゴールに設定していた3月までの投稿が一通り終わったということで、新卒の「記事投稿数」「記事view数」「累計view数」をランキング形式で振り返ってみたいと思います。

記事右下のview数は同じ人の複数閲覧はカウントされておらず、社内IPの閲覧もカウントしているためssekiさんがこのプロジェクト開始時に作成してくれたデータスタジオの集計データを使用していきます。
データは2018/3/29 17:35のものを使用しています。

記事投稿数TOP3!!

第3位 11記事!

第3位は11記事を書いたHelloWorld?さんです
文章が独特で内容についての知識がなくてもついつい最後まで読んでしまう…そんな記事が多い印象でした。
記事画像が毎回食べ物関連なのは謎です。

第2位 13記事!!

第2位は13記事を書いたssekiさんです
彼の記事はデータスタジオについてのみで13記事書かれています。
流石アナリスト、記事もとてもきれいに書かれていてデータスタジオについて全く知らなくても使いこなせる気になってきます。

第1位 16記事!!!

第1位は驚異の16記事を書いたLionさんです!
内容はゲームレビューやライフハック自身の経験談など様々でとても面白い記事が沢山ありますので見たことがない人はぜひご覧ください!

記事view数TOP3!!

第3位 AWSでRedashを使ってみる 1,540view

記事view数第3位はくじらさんのRedashがAWSで使えるようになる方法をまとめた記事でした!

第2位 ExcelでSQL文を発行する〜INSERT文〜 2,672view

第2位はknagataさんのExcelでINSERT文を発行する方法を示した記事でした。

第1位 立ち絵を魅力的に描く①【ポーズと表情でキャラクターを伝える】 9,078view

第1位は断トツの9000view越え、nocoさんの立ち絵の書き方のポイントを共有した記事でした!
pixiv等でも参考にして書いてみたなどで使われておりたくさんの人に見てもらえている記事になってます!

累計記事view数TOP3!

第3位 くじら 4,194view

第3位はActiveRecordやUnityなどについての記事が多かった くじらさんです!

第2位 inoooooocchi 4,659view

C#やUnityについての記事が多かったinoooooocchiさんが第2位にランクイン!
Unity関連の記事は検索されやすい傾向にありそうですね!

第1位 noco 11,329view

記事view数で断トツの1位を取ったnocoさんが累計記事view数でも1位でした!
かわいい絵がたくさんなのでさっきからこれしか言ってませんが是非ご覧ください!

累計記事view数はすべてアピゲー部(弊社の自社開発ゲーム部署名)の社員が総取りでした!

おわりに

いかがだったでしょうか。
17新卒で決めたDoRuby投稿が3月で終わり、気づいたらもう4月。1年間がとてもあっという間でした。
自分で投稿した記事のview数が伸びてるか確認するのが毎日のちょっとした楽しみでした。
記事を投稿することで自分の取り組んだタスクの復習にもなりとても勉強になりました。
17新卒が投稿する頻度は落ちるかと思いますが17新卒の記事かな?っていうのを見かけたら覗いてもらえると嬉しいです。

fugitive.vimでvim上でgit操作をしよう!

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

fugitive.vimプラグインを使うとvimでファイルの編集をしながらgitの操作ができます。
前回コミットとの差分の表示などを簡単に表示できるのでとっても便利です。

導入

dein.vimを使っているので.vimrcに以下を追記

  call dein#add('tpope/vim-fugitive')

 
これでvim上のコマンドでgitの操作が可能になります。
 


主なコマンド


:Gstatus

git statusが上部に表示される。
enter image description here

statusの確認だけでなく、
表示されているstatusのファイル名にカーソルを合わせてキーを打つことで動作を行える。

Dvimdiffで直前のコミットとの差分を表示
addとresetを切り替え
Enterファイルを表示

:Gdiff

vimdiffで直前のコミットとの差分を表示する。
自分はこれを一番多用してます。

enter image description here

:Gread

開いているファイルを直前のコミットの状態でみる。
 

:Gwrite

開いているファイルをgit addする。
 

:Gremove

開いているファイルをgit rmする。
 

:Gblame

開いているファイルをgit blameする。
見ていた行から表示してくれるので便利です。
普通のgit blameとは違いvimの設定の色がついてくれるので見やすいですが少し重いです。


かなり便利なので使ったことない人は一度使ってみてはいかがでしょうか。

github: https://github.com/tpope/vim-fugitive

source_locationでRubyを冒険

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

rubyのMethodやProcにはsource_locationというメソッドがあります。これを使うことでゴーストメソッドでも定義場所を発見できRubyコードの探索を簡単に行うことができます。

はじめに

新卒最終日になりました。くろすです。
今回はメソッド探索に使うと便利な Method#source_location, Proc#source_location の紹介をします。

Method Class

メソッドクラスは Object#methodによりオブジェクト化する際に使われるクラスです。
詳しいことはだいたいドキュメントに書いてありますが、Procオブジェクトと違いレシーバーの情報も持っていて、クロージャーではないというのが大きな特徴です。
すでに定義してあるメソッドをオブジェクトとして取ってこれるという点で便利だなと思います。

https://docs.ruby-lang.org/ja/latest/class/Method.html

source_location

さてそんなMethodClassの source_location ですが、色々話すより見てもらう方が早いと思います。

[1] pry(main)> ActiveRecord::Base.methods.grep(/transaction/)
=> [:transaction]
[2] pry(main)> ActiveRecord::Base.method(:transaction)
=> #<Method: Class(ActiveRecord::Transactions::ClassMethods)#transaction>
[3] pry(main)> ActiveRecord::Base.method(:transaction).source_location
=> ["path/to/gems/activerecord-4.1.15/lib/active_record/transactions.rb", 206]

使ってるgemが古いのは置いといてgemの中でもrubyで定義してあれば探すことができます。

[1] pry(main)> class Ghost
[1] pry(main)*   (1..3).each{|n| define_method("method_#{n}"){ puts n } }
[1] pry(main)* end
=> 1..3
[2] pry(main)> g = Ghost.new
=> #<Ghost:0x007f99da931d38>
[3] pry(main)> g.method_1
1
=> nil
[4] pry(main)> g.method(:method_1).source_location
=> ["(pry)", 2]

ご覧の通りdefine_methodでも余裕です。
が、method_missingを利用したゴーストメソッドはさすがに追い切れないです。

[1] pry(main)> Hash.method(:new).source_location
=> nil

ruby外で定義されているメソッドは残念ながら探せません。

終わりに

ぶっちゃけると define_method 対策として紹介しているので、define_methodを使わないようなコードではあまり使いどころがないと思います。
僕自身は開発にneovimを使うのでコードジャンプできなかった場合、ターミナルエミュレータを起動、highway、rails consoleからのsouce_location の順番でメソッドを探しています。
プログラムを読むために検索するというのは日常的なことだと思うのでその検索が少しでも早くなる手助けになればと思います。

社内ブログを書くことで得られた3つのこと

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回は社内ブログを書くことで得られたメリットをご紹介します。

①新たな知識が身に付く

記事としてまとめるために、自分の中の知識だけでは不安があります。
そのため、間違った理解をしていないか、なるべく多くの情報を集めます。

情報を集める中で
いままで気付けなかったことに気付くことができたり、
実際に記事には書いていなくても新たな知識として蓄積されます。

②思考力がつく

①で身に付けた知識や日々の仕事で学んだことをまとめることで
一度自分の思考が整理されます。
ごちゃごちゃしていた頭の中を整理することでより深く考えられるようになります。

アウトプットする機会は意識しないと意外と少ないもので、
その機会を得られるのは社内ブログを書くことの大きなメリットだと思います。

③文章を書く練習になる

文章を書くのは正直苦手でしたが10記事書く頃には大分抵抗も減りました。

当たり前ですが書かないと一生書けるようにはなりません。
まずは書く。書く習慣を持つキッカケになりました。

まとめ

①新たな知識が身に付く
②思考力がつく
③文章を書く練習になる

以上、社内ブログを書くことで得られる3つのことをご紹介しました。
社内ブログでなくとも何かを発信することは自分にとって大きなプラスになるはずです!

※本記事の内容は個人の見解によるものになります。

オフィスで簡単!ストレス解消方法!

0

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

今回はストレスをため過ぎないようオフィスで簡単にできるストレス解消方法をご紹介します。

ストレスとは

外部から刺激を受けたときに生じる緊張状態のこと。

外部からの刺激には、
天候や騒音など環境的要因や、睡眠不足などの身体的要因、
不安や悩みなどの心理的要因、人間関係が上手くいかない、
仕事のノルマや締め切りに追われてるなどの社会的要因があります。
日常的に起こる色々な出来事がストレスの要因になってしまうのです。

ストレスはためすぎると体調を崩したり、気持ちが不安定になったり、
さらには心の病気にもなってしまうこともあります。

【引用】厚生労働省:知ることからはじめよう、みんなのメンタルヘルス

今回はストレスをため過ぎないようオフィスで簡単にできるストレス解消方法をご紹介します。

こまめに席を立つ

ずっと同じ姿勢というのは体にもよくありません。
またそもそも集中力は長時間持たないので適度な休息が大切です。

トイレにいったり、軽くストレッチをしたり、何でも良いので席から立ちあがりましょう。
他の人の仕事の邪魔にならない程度であれば、誰かとお話するのも良いと思います。

ガムを噛む

噛むという行為が脳への血流を良くするため、
不安な気持ちを落ち着かせ、前向きな気持ちになれる効果があるそうです。

ストレス解消に役立つ食べ物でダークチョコレートも有名ですが、
チョコレートは太ってしまうんじゃないか…
という不安が新たなストレスに繋がってしまう可能性も。
その点、ガムであれば低カロリーなので安心です。

5年や10年後も忘れない出来事か自答する

仕事の中には嫌なことも理不尽なこともあると思います。
心が折れてしまいそうな出来事であっても一度冷静に、5年10年後、忘れられないようなことか
考えてみましょう。
大抵のことは忘れることができる、それほど重要なことではないはずです。

まとめ

・こまめに席を立つ
・ガムを噛む
・5年や10年後も忘れない出来事か自答する

以上、オフィスで簡単にできるストレス解消方法をご紹介しました。
どれも簡単に出来ることだと思うのでストレスが気になる方はぜひお試しください。

最近人気な記事