コピペコードで快適生活

明日使えるソースを自分のために

Rubyでたまにしか使わないけど便利なメソッドメモ

備忘のため。随時追加していく。

Ruby

# フィールドをもつモックオブジェクトを作る
Struct.new(:name, :tel).new('hogeo', '090xxxxxxxx')
# => #<struct name="hogeo", tel="090xxxxxxxx">

# irbでeach回して処理した後、そのリストを出力させたくない
list.each do |row|
  # 何かしらの処理
end; 0 # ここで ; 0 入れる。

# getter/setterがないインスタンス変数にアクセス
obj.instance_variable_defined?('@hoge')
obj.instance_variable_get('@hoge')
obj.instance_variable_set('@hoge', 'hogehoge')

# 余計な改行コードを chomp で消す
fr = File.open('ids.txt', 'r')
line = fr.gets
# => "0000a432-67cb-4b07-8bba-58780616f6c7\n"
line = fr.gets.chomp
# => "0000a5bd-cf86-4eda-be5e-0b81dafa5cd0"
fr.close

Rails

# 引数の文字列で指定した名前で定数を探す
'::MyApp::User'.constantize
# => MyApp::User(id: integer, first_name: string, last_name: 

# ハッシュにシンボルでも文字列でもアクセスできるように
hash = { hoge: 'fuga' }.with_indifferent_access
hash[:hoge]  #=> "fuga"
hash['hoge'] #=> "fuga"

# モデルやフィールドの日本語名を取得
def t_ar(model, attr = false)
  if attr
    return model.human_attribute_name(attr)
  else
    return model.model_name.human
  end
end

# ハッシュの一部をフィルターする
filter = ActionDispatch::Http::ParameterFilter.new(['email', 'password'])
filterd_params = filter.filter(params)

# 生SELECT文を書く
con = ActiveRecord::Base.connection
result = con.select_all('SELECT name FROM users')
result.to_a

ワンライナー

# yaml文法チェック
cat foo.yml | ruby -r yaml -e 'YAML.load STDIN'
# クエリ文字列をURLエンコード
require 'cgi'
query.split('&').map{|kv| kv.split("=").map{|_kv| CGI.escape(_kv) }.join("=") }.join('&')

DeveloperConsoleに貼って、さっとCORSのチェックをやりたいとき用JS

xhrReq = function(url) {
  let xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  // プリフライト(OPIONSメソッドによる事前確認)をする場合は、
  // カスタムヘッダをセットする
  xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
  
  xhr.onreadystatechange = function(){
    if (xhr.readyState === 4 && xhr.status === 200){
      console.log(xhr.responseText);
    }
  };
  xhr.send(null);
};

自動ログインするブックマークレット

↓のコードを適宜修正して、ブックマークのURL欄にコピペする。

javascript:(function(){document.querySelector('input[name=login_id]').value = 'LOGIN_ID'; document.querySelector('input[name=password]').value = 'PASSWORD'; document.querySelector('input[name=submit]').click(); }());

prependでクラスメソッドを拡張する

singleton_classにprependすればOK。

class Hoge
  def self.hogehoge(*args)
    puts 'hogehoge'
  end
end

Hoge.hogehoge
# => hogehoge

Hoge.singleton_class.prepend Module.new {
  def hogehoge(*args)
    super(*args)
    puts 'extended hogehoge'
  end
}

Hoge.hogehoge
# => hogehoge
# => extended hogehoge

# 継承ツリー
Hoge.ancestors
# => [Hoge, Object, Kernel, BasicObject]
Hoge.singleton_class.ancestors
# => [#<Module:0x007fc15e090f70>, #<Class:Hoge>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]

class SomeClass
  class << self
    def some_classmethod
      "Hello"
    end
  end
end

SomeClass.some_classmethod
#=> Hello

singleton_class(特異クラス)とは、
すべてのオブジェクトが持つ自分だけの隠しクラスのこと。
インスタンスに独自に定義したメソッド(特異メソッド)は、
この特異クラスに定義しているという扱いらしい。

参考
https://qiita.com/ponoda/items/bfcf5533b532a6d32111
https://allabout.co.jp/gm/gc/453836/#note1

複数のサーバで一度にsshコマンドを実行したい

メモ。

HOSTS="host01 host02 host03"
for host in ${HOSTS}; do
echo $host
ssh -t $host <<EOC
hostname
sudo service td-agent restart
sleep 1
ps aux | grep td-agent
EOC
echo "--------------------"
done

参考
SSHで一気にコマンドいろいろ投げたい