読者です 読者をやめる 読者になる 読者になる

うまとま君の技術めも

2015年新卒入社した社畜の勉強内容などなど

Drawableに設置したpngファイルのオリジナルサイズを取得する

AndroidにてDrawableに設置したpngファイルのサイズを取得しようとしたら、ちょっとはまったのでメモ。

前提

drawableに 50 * 50 px の画像ファイルを設置。
res/drawable/sample.png

画像サイズを取得

リソースIDからBitmapを生成して#getWidth, #getHeightでサイズを取得したら、 実際のサイズとは異なる値が取得される。。。

Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.sample);
int w = b.getWidth();
int h = b.getHeight();
// w => 150; h => 150;

そんな時はBitmapFactory.Optionsから値を取得してあげれば、 オリジナルの画像サイズが取得出来ました( ´ー`)フゥー...

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.sample, options);
int w = options.outWidth;
int h = options.outHeight;
// w => 50; h => 50;

参考

http://stackoverflow.com/questions/8855036/incorrect-image-dimensions-in-android-when-using-bitmap

Enumerable#map and Array#flatten vs Enumerable#flat_map

目的

  • Enumerable#map, Array#flatten と Enumerable#flat_map でどちらがパフォーマンスに優れているかを調べる。

環境

Enumerable#flat_map

flat_map (Enumerable) - APIdock : http://apidock.com/ruby/Enumerable/flat_map

ベンチマーク

require 'benchmark'

n = 1000
array = Array.new(100) { |i| Array.new(i) { |j| j } }

Benchmark::CAPTION
Benchmark.bm do |x|
  x.report('flat_map') { n.times { array.flat_map { |a| a } } }
  x.report('flat map') { n.times { array.map { |a| a }.flatten(1) } }
end
       user     system      total        real
flat_map  0.030000   0.010000   0.040000 (  0.036725)
flat map  0.260000   0.020000   0.280000 (  0.271837)

まとめ

map , flattenではなくflat_mapを使ったほうが速くなっていますね。

ただ、flat_mapでは1段階までしか平坦化されないで使用する際には注意が必要かもしれないです。

irb(main):055:0> [[1, 2], [[3, 4, 5]]].flat_map { |x| x }
=> [1, 2, [3, 4, 5]]

Railsで独自クラスにバリデーションを実装してみる

環境

独自クラスにValidationを実装

独自クラスでRailsのValidationを実装したい場合はActiveModel::Validationsをincludeしてあげればよいらしい。

class Hoge
  include ActiveModel::Validations

  validates :hoge_id, presence: true
  
  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end
end

これで、大丈夫かと思ったがNoMethodErrorが出てしまった。

[1] pry(main)> Hoge.new(hoge_id: 100)
NoMethodError: undefined method `hoge_id=' for #<Hoge:0x007fc71ce47bf0>
from /path/to/hoge.rb:8:in `block in initialize'

なので、attr_accessor :hoge_idを指定してあげればエラーは消えた.

class Hoge
  include ActiveModel::Validations

  attr_accessor :hoge_id # 追加

  validates :hoge_id, presence: true
  
  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end
end

これで、ひとまず独自クラスでもバリデーションを行うことが出来るようになりました。

[5] pry(main)> hoge = Hoge.new(hoge_id: nil)
[6] pry(main)> hoge.valid?
=> false
[7] pry(main)> hoge.errors.full_messages
=> ["Hogeを入力してください。"]

参考

CoffeeScriptのファットアローって何だ?

ファットアロー

jQueryのコールバック関数で呼ばれた関数でthisを使うと関数内のjQueryオブジェクトを指しているため、
that = @等と関数外で別の変数に置き換えて使用することがあると思います。

coffee

class User
  constructor: (first_name, last_name) ->
    @full_name = "#{first_name} #{last_name}"
    
    that = @
    $("#action-hello").click ->
      alert "My name is #{that.full_name}."

js

var User;

User = (function() {
  function User(first_name, last_name) {
    var that;
    this.full_name = "" + first_name + " " + last_name;
    that = this;
    $("#action-hello").click(function() {
      return alert("My name is " + that.full_name + ".");
    });
  }

  return User;

})();

そんな時、アロー->ではなくファットアロー=>を使ってあげると
@に対してスコープ外のthisへと自動的に置き換えを行ってくれます。

coffee

class User
    constructor: (first_name, last_name) ->
    @full_name = "#{first_name} #{last_name}"
    
    $("#action-hello").click =>
        alert "My name is #{@full_name}."

js

var User;

User = (function() {
  function User(first_name, last_name) {
    this.full_name = "" + first_name + " " + last_name;
    $("#action-hello").click((function(_this) {
      return function() {
        return alert("My name is " + _this.full_name + ".");
      };
    })(this));
  }

  return User;

})();

感想

ファットアローなんてものがあったんですね、知らなかった自分が情けないです。。。

Railsでf.selectにclassが設定できない時

環境

f.select

<%= form_for @user do |f| %>
  ...
  <%= f.select :job, { engineer: "Engineer", ... }, class: "myclass" %>
  ...
<% end %>

ここでセレクトタグに.myclassが設定されていることが期待されるが、 実際に生成されるHTMLは下記のようになる。

<select id="user_job" name="user[job]">
  <option selected="selected" value="engineer">Engineer</option>
  ...
</select>

classが設定できない時の対処法

<%= form_for @user do |f| %>
  ...
  <%= f.select :job, { engineer: "Engineer", ... }, {}, { class: "myclass" } %>
  ...
<% end %>

これでclassが設定されたHTMLが出力されるはずです。

<select class="myclass" id="user_job" name="user[job]">
  <option selected="selected" value="engineer">Engineer</option>
  ...
</select>

参考

Railsでdefault_scopeの解除方法

環境

default_scopeの設定方法

orderwhere文などをdefault_scopeメソッドに渡してあげればおk

class User < ActiveRecord::Base
  ...
  default_scope { order(email: :asc) }
  default_scope { where(deleted_at: nil) }
  ...
end

orderの解除方法

reorderorderのみ解除できる。

User.all
    #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL  ORDER BY `users`.`email` ASC"
User.reorder(nil)
    #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL
User.reorder(id: :desc)
    #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL  ORDER BY `users`.`id` DESC"

特定のscopeの解除方法

exceptまたはunscopeで解除することが出来る。
unscopeの方はexceptよりも細かい設定をすることが出来るようです。

User.all
    #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL  ORDER BY `users`.`email` ASC"
User.except(:order)
User.unscope(:order)
    #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL
User.except(:where)
User.unscope(:where)
User.unscope(where: :deleted_at)
    #=> "SELECT `users`.* FROM `users`  ORDER BY `users`.`id` DESC"

感想

今回は環境がRails4だったのでRails3などでは結果が違うかもしれないですね。

参考

Macで作るLaravel 4.1 開発環境

環境

  • OS X 10.9.2
  • Homebrew 0.9.5
  • PHP 5.5
  • Laravel 4.1

PHP 5.5 をインストール

$ curl -s http://php-osx.liip.ch/install.sh | bash -s 5.5

pathを追加する

$ vim ~/.bash_profile
export PATH=/usr/local/php5/bin:$PATH

設定ファイルを反映させる

$ source ~/.bash_profile
$ php -v
PHP 5.5.12 (cli) (built: May 17 2014 15:21:52)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans

php_mcryptのインストール

brewphp_mcryptをインストール

$ brew install mcrypt

composerのインストール

$ curl -sS https://getcomposer.org/installer | php -d detect_unicode=Off
$ mv composer.phar /usr/local/bin/composer
$ composer --version
Composer version 0c343f925ad578a9da4d9a4cfff4e91b500d206c 2014-05-14 09:25:20

Laravelのプロジェクトを作成

適当なディレクトリにプロジェクトを作成

$ composer create-project laravel/laravel myapp --prefer-dist
$ cd myapp
$ php artisan serve

http://localhost:8000にアクセスして下記画面が表示されていればおk

laravel_welcome

参考