20190727のRubyに関する記事は16件です。

Rakeタスクの実装

本日の学習内容のアウトプット。

Rakeタスクとは、ターミナルなどのコマンドライン上からアプリケーションを実行できる機能の一つです。
CSVデータのインポートなどがRailsコンソールなどを使用しなくても簡単に処理ができるようになります。

Rakeタスクの実装

Rakeタスクの実装は以下のコマンドを入力します。

rails new rake タスク名

すると、lib/tasks/task_sample.rakeが生成されるのでこのファイルに記述して行きます。

namespace :import_csv do
  # rake import_csv:users
  desc "User CSVデータのインポート #実行処理の説明"
  task users: :environment do
    User.import('db/csv_data/user_data.csv')
  end
end

Railsでは、デフォルトで設定されているRakeタスクがあります。
これらのタスクは、アプリを作成する際自動で定義されます。
以下のコマンドをターミナルに入力すると、先ほど作成したRakeタスクと一緒に表示されます。

rake -T

表示されたRakeタスク

user-no-MacBook-Pro:csv_data user$ rake -T
rake about                              # List versions of all Rails framew...
rake active_storage:install             # Copy over the migration needed to...
rake app:template                       # Applies the template supplied by ...
rake app:update                         # Update configs and some other ini...
rake assets:clean[keep]                 # Remove old compiled assets
rake assets:clobber                     # Remove compiled assets
rake assets:environment                 # Load asset compile environment
rake assets:precompile                  # Compile all the assets named in c...
rake cache_digests:dependencies         # Lookup first-level dependencies f...
rake cache_digests:nested_dependencies  # Lookup nested dependencies for TE...
rake db:create                          # Creates the database from DATABAS...
rake db:drop                            # Drops the database from DATABASE_...
rake db:environment:set                 # Set the environment value for the...
rake db:fixtures:load                   # Loads fixtures into the current e...
rake db:migrate                         # Migrate the database (options: VE...
rake db:migrate:status                  # Display status of migrations
rake db:rollback                        # Rolls the schema back to the prev...
rake db:schema:cache:clear              # Clears a db/schema_cache.yml file
rake db:schema:cache:dump               # Creates a db/schema_cache.yml file
rake db:schema:dump                     # Creates a db/schema.rb file that ...
rake db:schema:load                     # Loads a schema.rb file into the d...
rake db:seed                            # Loads the seed data from db/seeds.rb
rake db:setup                           # Creates the database, loads the s...
rake db:structure:dump                  # Dumps the database structure to d...
rake db:structure:load                  # Recreates the databases from the ...
rake db:version                         # Retrieves the current schema vers...
rake dev:cache                          # Toggle development mode caching o...
rake import_csv:users                   # User CSVデータのインポート
rake initializers                       # Print out all defined initializer...
rake log:clear                          # Truncates all/specified *.log fil...
rake middleware                         # Prints out your Rack middleware s...
rake notes                              # Enumerate all annotations (use no...
rake notes:custom                       # Enumerate a custom annotation, sp...
rake restart                            # Restart app by touching tmp/resta...
rake routes                             # Print out all defined routes in m...
rake secret                             # Generate a cryptographically secu...
rake stats                              # Report code statistics (KLOCs, et...
rake test                               # Runs all tests in test folder exc...
rake test:db                            # Run tests quickly, but also reset db
rake test:system                        # Run system tests only
rake time:zones[country_or_offset]      # List all time zones, list by two-...
rake tmp:clear                          # Clear cache, socket and screensho...
rake tmp:create                         # Creates tmp directories for cache...
rake yarn:install                       # Install all JavaScript dependenci...

真ん中あたりに作成されたRakeタスクがあります。

コマンドの実行

user-no-MacBook-Pro:csv_data user$ rake import_csv:users

Rakeタスクは非常に便利な機能だと思ったのでもっと使ってみて学習していきたいです。

参考
https://qiita.com/yoshito410kam/items/26c3c6e519d4990ed739
https://qiita.com/suzuki_koya/items/787b5562d2ae1a215d94

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

投稿日時を日本時間表記にする方法

はじめに

ruby on railsでチャットアプリ作成中
メッセージを投稿すると日時の表記が日本時間になっておらず表示のされ方もなんか見にくい。。

解決方法

config/application.rb
config.time_zone = 'Tokyo' を追記して時間設定を日本にする。
Image from Gyazo

app/views/messages/_messages.html.haml 
.strftime("%Y-%m-%d %H:%M") を追記して表示の仕方を見やすくしてあげる。
Image from Gyazo

もし非同期通信とか使っていたらこっちにもちゃんと変換されるようににも追記しておきましょう。
messages/index.json.jbuilder
Image from Gyazo

結果

こんな感じで表示されればおk!
Image from Gyazo

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsでダミーのユーザーデータをたくさん用意する方法

3行で

  • いちいち新規作成などする手間を省く
  • seedファイルにデータを書き込む
  • ターミナルで raiks db:seed を実行

( ´∀`)<詳しく書きますね

ユーザーデータが複数必要なとき

たとえばインクリメンタルサーチの実装などで、データベースのUsersにたくさんデータがほしい場合があると思います。
そこでユーザーの新規作成(Sign Up)などでデータを作っていては時間がかかってしまいますね。

seeds.rbに作りたいデータを書き込みます

db/seeds.rbを編集します。

seeds.rb
p "create Users"
User.create!(
  email: 'user1@exam.com',
  password: 'aaaaaaaa',
  name: 'ぽーる',
  self_introduction: 'えへへ'
)
User.create!(
  email: 'user2@exam.com',
  password: 'aaaaaaaa',
  name: 'じょん',
  self_introduction: 'どーも'
)
.
.
.

1行目にはのちほどターミナルでコマンドを実行したときに表示させるための文字列を書いておきます。

次に テーブル名.create! を書きます。
それからカッコ内にユーザーの情報を書いていきますが、それぞれカラムに対応している項目にしてあげてください。必ずしも上の例と同じにはなりません。emailは重複しないように注意!

rails db:seed を実行

好きなだけユーザーとその情報を書いたら、ターミナルで rails db:seed を実行してください。
先ほど書いておいた create Users の表示とともに、ユーザーが作られています。データベースを確認してみましょう!

( ´∀`)<読んでくれてありがとう

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者向け】bundler、Gemfile、Gemfile.lockの関係性について図でまとめてみた

Ruby on RailsでWebアプリケーション(以降ではRailsアプリと略します)を開発をするにあたり、gemの活用は開発効率をあげるために重要です。

Railsアプリ開発でgemを利用する機会は多くありますが、どのようにgemが管理されているかということについて理解をする機会は少ないかもしれません。

今回は『bundler』『Gemfile』『Gemfile.lock』といった、gemの管理を理解する上で重要な役割をもつ概念について紹介をしたいと思います。

2019年7月27日追記
@scivola さんにコメントで補足説明をしていただきました。
非常に参考になる内容ですので、こちらのコメントもぜひ読んでいただければと思います。

bundlerとは

『bundler』は依存関係にあるgemの依存関係やバージョンを管理してくれるgemです。

インストールしようとしているgem自身もほかのgemを利用しているケースがあります。その場合、依存関係にあるgemもあわせてインストールする必要があります。

また、各gemにはバージョンが設定されているのですが、同じgemでもバージョンが異なるとRailsアプリの挙動を変えてしまったり、他のgemに影響を与えてバグを発生させたりする可能性があります。

これらの問題を解決してくれるのがbundlerです。

bundlerを利用することで『依存関係にあるgemの一括インストール』『gemのバージョン管理』ができるようになります。

Gemfileとは

『Gemfile』とはRailsアプリで利用するgemの一覧を管理するファイルです。

『bundlerによってインストールされるgemはどこで管理されているのか?』
それが今から紹介するGemfileの役割です。

bundle installというコマンドでgemをbundlerを利用してインストールするのですが、その際にはGemfileに記載されているgemの一覧を参照し、まだインストールされていないgemがあればインストールを行います。

ですので、Railsアプリで新しくgemを追加したいという場合はGemfileにgemの名前を追記していくことになります。

Gemfile、bundleコマンド、gemの関係性および処理の流れを図で表現すると以下のようになります。
gemfile-overview-880.png

Gemfile.lockとは

『Gemfile.lock』はGemfileをもとに実際にインストールされたgemの一覧とバージョンが記載されたファイルです。

Gemfile.lockには依存関係にあるgemも含め、bundlerによってインストールされた全てのgemとそのgemのバージョンが記載されています。

Gemfile.lockはGemfileをもとにbundlerによってインストールされたgemの結果を出力するファイルです。そのため、基本的には手動で更新することはありません。
bundle installもしくはbundle updateをすることでGemfile.lockは自動で更新されます。

Railsアプリにインストールされたgemと、Gemfile.lockの関係性を図で表現すると以下のようになります。

gemfilelock-overview-1024x780.png

GemfileとGemfile.lockの比較

GemfileとGemfile.lockの違いについて表にすると以下のようになります。

Gemfile Gemfile.lock
記載されているgem bundlerでインストールするgem bundlerでインストールしたgem
更新タイミング bundleコマンド実行前 bundleコマンド実行後
更新方法 手動更新 自動更新

『Gemfileの内容をもとにbundlerがgemをインストール → インストールしたgemの結果をGemfile.lockに記載』という一連の流れを図としてまとめると以下のようになります。

bundle-gem-overview-880.png

さいごに

以上でRailsアプリにおける、bundler、Gemfile、Gemfile.lockの役割の紹介および図解を終わります。

詳細については『Gemfile?bundler?Rails開発するなら理解しておきたいgem管理の基礎知識』で紹介していますので、興味のある方はご覧になってください。

ツイッター(@nishina555)やってます。フォローしてもらえるとうれしいです!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

RailsでCSVダウンロード後の画面のリロード

あるデータの一覧のCSVダウンロードした後に画面の情報が変わっていることを確認させる必要があったときの開発メモ。

controllerからだとリダイレクトは出来ない。

自分の考えとしてはcontroller内のアクションにダウンロードした後にリダイレクトをさせれば良いと考え以下のように記載。

def download
    respond_to do |format|
      format.csv do
        send_data render_to_string, filename: "#{__method__}_#{Time.zone.now.strftime('%Y%m%d')}.csv", type: :csv
      end
    end
    redirect_to hoge_url
end

ただこれだとDouble renderとなり起こられてしまう。

解決 jsでリダイレクトさせる

slim

.text-right
  = link_to 'CSV', download_path(format: :csv),
    class: 'btn btn-link', id:'download-csv', target: '_blank'

js

  $('#download-csv').click -> location.reload()

参考: http://tshidax.hatenablog.com/entry/2017/09/11/120000

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ActiveSupportのslice!メソッドがトリッキーな動きをする

経緯

ActiveRecordのvalidationメソッドを読んでいて出てきたActiveSupporのslice!メソッドがトリッキーと自分には感じる動きをしたので書いた。
Railsはv5.2.3。
【PR】ちなみにこういうったコードリーディングの勉強会をよく開催しているので興味ありましたらこちらのリンクを見てね!過去開催例はこちら

概要

  • sliceメソッドの動作はこうなります。引数に渡されたkeyをHashとして返します。またもちろんレシーバーには影響はありません。
[43] pry(main)> require 'active_support'
=> true
[44] pry(main)> require 'active_support/core_ext'
=> true
[60] pry(main)> some_hash = {
[60] pry(main)*   key_a: "some content",  
[60] pry(main)*   key_b: "some content",  
[60] pry(main)*   key_c: "some content"  
[60] pry(main)* }  
=> {:key_a=>"some content", :key_b=>"some content", :key_c=>"some content"}
[61] pry(main)> some_hash.slice(:key_a, :key_b)
=> {:key_a=>"some content", :key_b=>"some content"}
[62] pry(main)> some_hash
=> {:key_a=>"some content", :key_b=>"some content", :key_c=>"some content"}
  • 一方slice!メソッドはこうなります。引数に渡されたkeyをHashとして返ってきて、渡されなかったものがレシーバーから消されるのかな、と思ったらその逆でした。渡されなかったkeyのHashが返ってきて、返ってきたものはレシーバーから消されます。言い換えると、引数にはレシーバーに残したいkeyを指定するということになります。
[63] pry(main)> some_hash.slice!(:key_a)
=> {:key_b=>"some content", :key_c=>"some content"}
[64] pry(main)> some_hash
=> {:key_a=>"some content"}

コードを見てみる

sliceメソッドのコードと、slice!メソッドのコードを見るとそう書いてあるので、なるほどという感じ。

参考

https://qiita.com/mah_lab/items/ed10bae99105ea2fd8bd

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SassとCompassをVM環境(CentOS7)に入れてみた

目的

業務効率化

前提

  1. OracleのVirtualBoxインストール済であること
  2. WindowsにVagrant環境インストールであること

OS情報

[root@localhost /]#  cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)

SassとCompassのインストール方法

SassとCompassはRuby上で動くプログラムなので、Rubyや関連プログラムをインストールしておく必要があります。
Linux系OSの場合、Ruby はインストール済みの場合が多いので、ターミナルで以下のコマンドを発行してインストール済みかを確認します。

[root@localhost /]# yum list installed | grep ruby

Ruby以外にも必要なプログラムがあるので、下記もインストール済みか確認

[root@localhost /]# yum list installed | grep ruby-devel
[root@localhost /]# yum list installed | grep rubygems
[root@localhost /]# yum list installed | grep gcc

これらがインストールされていない場合は、以下準備編から読む。インストールされてある場合は、準備編は読み飛ばしてください

準備編

Rubyのインストールに必要なモジュールを入れる

1). rbenvのインストール

2). gitのインストールが済んでない場合は以下コマンド実行

[root@localhost /]#  yum install git

3). rbenvを取得します。

[root@localhost /]# git clone https://github.com/rbenv/rbenv.git ~/.rbenv

4). rbenvのパスを通して有効化します。

[root@localhost /]# echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
[root@localhost /]#  ~/.rbenv/bin/rbenv init
[root@localhost /]#  source ~/.bash_profile

5). rbenvがインストールされたことを確認します。

[root@localhost /]# rbenv -v
rbenv 1.1.2-2-g4e92322

6). ruby-buildのインストール

ruby-buildを取得します。

[root@localhost /]#  git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

7). ruby-buildをインストールします。

[root@localhost /]#  ~/.rbenv/plugins/ruby-build/install.sh

8). ruby-buildがインストールできるとrbenvのpluginであるrbenv installコマンドが使用できる

[root@localhost /]#  rbenv install -l

インストール可能なRubyのバージョンが一覧で表示されます。

Available versions:
  1.8.5-p52
  ・
  ・
  ・
  rbx-2.2.3
  rbx-2.2.4
  rbx-2.2.5
  rbx-2.2.6
  rbx-2.2.7
  rbx-2.2.8
  rbx-2.2.9
  rbx-2.2.10
  rbx-2.3.0
  rbx-2.4.0
  rbx-2.4.1
  rbx-2.5.0
  ・
  ・
  ・

Rubyのインストール

1). Rubyをインストールするのに必要なパッケージを先にインストールします。

[root@localhost /]# yum install -y openssl-devel readline-devel zlib-devel 

2).次にRubyのインストールをします。

[root@localhost /]# rbenv install 2.4.1

3).Rubyへのパスを通して有効化します。

[root@localhost /]# echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
[root@localhost /]# source ~/.bash_profile

4).rbenvで2.4.1を使用するように設定します。

[root@localhost /]# rbenv global 2.4.1

5).Rubyのバージョンが表示されればインストール完了です。

[root@localhost /]# ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]

Ruby以外の必要なプログラムをインストール

[root@localhost /]# yum -y install ruby-devel
[root@localhost /]# yum install rubygems
[root@localhost /]# yum install gcc

gemを更新

[root@localhost /]# gem update --system

gem はRuby言語用のパッケージ管理システムです。
このgem を使って Sass と Compass をインストールします。

ここまで準備できたら以下へ

Sass と Compass をインストール

[root@localhost /]# gem install compass 
[root@localhost /]# gem install sass

[root@localhost /]# sass -v
Ruby Sass 3.7.4
[root@localhost /]# compass -v
Compass 1.0.3 (Polaris)
Copyright (c) 2008-2019 Chris Eppstein
Released under the MIT License.
Compass is charityware.
Please make a tax deductable donation for a worthy cause: http://umdf.org/compass

プロジェクトを作成

プロジェクトを作りたいフォルダ(プロジェクトのパス)に移動してコマンド実行

$ cd /vagrant/sample

$ compass create --sass-dir "scss" --css-dir "css" --javascripts-dir "js" --images-dir "img"

※sassファイルはscssフォルダへ、CSSファイルはcssフォルダに作成されます。
※JavaScriptファイルはjsフォルダ、画像ファイルはimgフォルダを参照してくれるようになります。

image.png

※ マウントしてあれば、ホスト側でコマンドを実行した時の確認が取れます。

config.rbの設定

config.rb
require 'compass/import-once/activate'
# Require any additional compass plugins here.

# Set this to the root of your project when deployed:
http_path = "/"
css_dir = "css"
sass_dir = "scss"
images_dir = "img"
javascripts_dir = "js"

# You can select your preferred output style here (can be overridden via the command line):
# output_style = :expanded or :nested or :compact or :compressed

# To enable relative paths to assets via compass helper functions. Uncomment:
# relative_assets = true

# To disable debugging comments that display the original location of your selectors. Uncomment:
# line_comments = false


# If you prefer the indented syntax, you might want to regenerate this
# project again passing --syntax sass, or you can uncomment this:
# preferred_syntax = :sass
# and then run:
# sass-convert -R --from scss --to sass scss scss && rm -rf sass && mv scss sass

Sass 作ってみる

test.scss
$font-stack: Helvetica, sans-serif;
$primary-color: #333;
$hogeValue: 10px;

body {
  font: 100% $font-stack;
  color: $primary-color;
}

@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
     -moz-border-radius: $radius;
      -ms-border-radius: $radius;
          border-radius: $radius;
}

nav {
  ul {
    margin: $hogeValue;
    padding: $hogeValue;
    list-style: none;
  }

  li { @include border-radius(10px); }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}

image.png

コンパイルしてブラウザ表示まで

$ cd scss作成した作業パス

「test.scss」を「test.css」にコンパイルする(同じフォルダ内でコンパイル)

$ sass test.scss:test.css

フォルダをまたいでコンパイル(sassフォルダ、cssフォルダが別の場合)

$ cd sassフォルダ
$ sass test.scss:../css/test.css
test.css
body {
  font: 100% Helvetica, sans-serif;
  color: #333; }

nav ul {
  margin: 10px;
  padding: 10px;
  list-style: none; }
nav li {
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  -ms-border-radius: 10px;
  border-radius: 10px; }
nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none; }

/*# sourceMappingURL=test.css.map */

image.png

マウント先のホストOSでブラウザ表示してみる ↓

image.png

参考

https://github.com/sass/sass
https://qiita.com/AsagiriDesign/items/db12237796d1e7c9e632
https://qiita.com/m0nch1/items/b01c966dd2273e3f6abe
http://book.scss.jp/code/c2/07.html
https://liginc.co.jp/designer/archives/11623
https://rfs.jp/sb/css/sass/sass05_linux_sass.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rbenvの使い方まとめ

Ruby初学者なので、rbenvの基礎的な使用方法から自分用にまとめます。

基本的には公式リポジトリを見ながら書いていきます。

rbenvとは?

Rubyのバージョン管理を行ってくれるツール。
開発環境に複数バージョンのRubyをインストールし、切り替えることができます。

インストール・設定

以下、Macを前提で記載します。

# インストール(ruby-buildも入れておく)
$ brew install rbenv ruby-build

~/.bash_profileに以下の内容を追記します。

eval "$(rbenv init -)"
# 変更内容を適用
$ source ~/.bash_profile

# インストール確認
$ rbenv -v

基本的な使い方

Rubyのインストールとバージョン切り替え

Rubyのバージョンを指定してインストールします。

# まずはインストール可能なバージョンを調べる
$ rbenv install -l
Available versions:
  1.8.5-p52
  1.8.5-p113
  1.8.5-p114
  1.8.5-p115
  1.8.5-p231
  1.8.6
 ...

# 記載時点では2.6.3が安定版のようなので、2.6.3を入れる
# ※[-dev]や[preview]と書いていない
$ rbenv install 2.6.3

# 私の環境ではエラーになりました。。。
BUILD FAILED (OS X 10.14.5 using ruby-build 20190423)
# オプションつけると通るらしい
$ RUBY_CONFIGURE_OPTS="--disable-dtrace" rbenv install 2.6.3

# インストールされているバージョン一覧
$ rbenv versions
2.6.3

# 使用するRubyのバージョン指定
$ rbenv global 2.6.3

上記の場合は全体で使用するRubyのバージョンを設定しますが、
任意のディレクトリ配下だけ別のバージョンを使用することもできます。

# 全体のバージョン
$ ruby -v
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]

# 任意のフォルダに移動
$ cd hoge

# hogeの中だけ2.6.0(オプションは割愛)
$ rbenv install 2.6.0
$ rbenv local 2.6.0

# .rbenv-version が作成される
$ ls -a
.               ..              .ruby-version

$ ruby -v
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-darwin18]

その他機能

shell

コマンドラインで使用するRubyのバージョンを一時的に変更します。

# 現在のバージョン
$ rbenv versions
  system
  2.6.0
* 2.6.3 (set by /Users/iwakura/.rbenv/version)

$ rbenv shell 2.6.0

# 確認
$ rbenv versions
  system
* 2.6.0 (set by RBENV_VERSION environment variable)
  2.6.3

# 元に戻す
$ rbenv shell --unset
$ rbenv versions
  system
  2.6.0
* 2.6.3 (set by /Users/iwakura/.rbenv/version)

which

rbenv内にインストールされているコマンドのフルパスを表示します。

$ rbenv which gem
/Users/iwakura/.rbenv/versions/2.6.3/bin/gem

whence

引数に指定したコマンドがインストールされているバージョンを表示します。

# 現在2.6.3と2.6.0がインストールされている
# rackupは2.6.3にのみ存在
$ rbenv whence rackup
2.6.3

環境変数

rbenvで使用する環境変数について記載します。

名前 デフォルト値 説明
RBENV_VERSION rbenv shellで使用するRubyのバージョンを設定
RBENV_ROOT ~/.rbenv rbenvでインストールした各バージョンのファイル等が配置されるパスを指定
RBENV_DEBUG デバック情報を出力するらしい(rbenvの挙動確認用?)
RBENV_HOOK_PATH rbenv hooks用らしいけど何かよく分からない
RBENV_DIR $PWD .ruby-versionの検索先

まとめ

一部雑な記載になってしまいましたが、基本的なことは学べました。
今後Rubyを使用して仕事することになるので、言語仕様も含めてしっかり学びたいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rubyの自己代入(||=)とはこんな仕組みです

仕事などで人の書いたRubyのコードを見ていると、以下のようなコードを見かけることがあると思います。

test ||= 10
p test # => 10

sample = 20
sample ||= 'sample'
p sample # => 20

sample_txt ||= 'sample'
p sample_txt # => "sample"

||=これは、いわゆる自己代入とググればよく出てくるやつです。

しくみは、変数(test / sample / sample_txt)の中身が、
nilまたは、falseであれば、||=の右辺にある値を変数に代入する。
nilまたは、false以外であれば、変数の値をそのまま利用する。

と言う感じです。

test ||= 1

上記のようなコードは、以下のようなコードを見ると理解しやすいかなと思います。

test || (test = 1)
p test # => 1

論理演算子である(||)は、式全体の真偽が確定した時点で評価された値が戻り値となります。

上記の場合、右辺の変数(test)はnilなので、1が評価され、戻り値として返されます。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaとC++は学ぶな!!初心者が学ぶべき言語【さらに厳選】

注意事項

この記事には以下の要素が含まれます。苦手な方はご注意くださいね。

  • Pythonへの熱いdisり
  • C言語なんてなかった
  • JDK問題について深く知らないので怖がっている
  • いわゆる関数型言語に言及しないスタイル(F#とかScalaとか?)

はじめに

JavaとC++は学ぶな!!初心者が学ぶべき言語【厳選】

という記事が出ているのですが、C++erとしては遺憾の意を示さざるを得ません。そのうえでこれからプログラミングを始める人におすすめする言語を紹介します。え、C++?初心者にはおすすめできません。

初心者におすすめする言語が満たすべき要件

  • 人口がそこそこいる
  • Windowsでも容易に開発環境が構築できる
  • 動作結果が目で見てわかる
  • コンパイルしなくていい
  • 言語規格が少なくとも5年以内に更新されている
  • 言語規格が後方互換性を備えていること
  • 日本語資料が豊富にあること
  • 非力なPCでも開発できる

人口がそこそこいる

プログラミング言語を作っている人もたくさんいるので無限にプログラミング言語は存在し得るわけですが、さすがにある程度ユーザー数がいない言語を薦めるわけにはいきません。

Windowsでも容易に開発環境が構築できる

例えばPythonはなぜかWindowsだと動かないという事態によく遭遇します(私だけ・・・?)。初心者にエラー文を読んで原因を切り分けさせるのは無理です。

他の言語でもWindowsで完璧に動くぜ!って言うのは以外と少ないです。Rubyはだいぶ頑張っていると思いますがそれでも特に音声やグラフィックが絡むとcannot load such fileと言われがちです(なぜかmsys2 mingw64 rubyでruby2dが使えない、チャットで問い合わせ中)。

動作結果が目で見てわかる

初心者はコンソールなんてまともに扱えませんし、"Hello world!"っていう文字を見せられても感動できません。

なんか図形が動くとかそういう視覚に容易に訴えられるのが望ましいです。

C++はGUIを作るのが極めて難しいのでこういうのは無理です(2D graphics標準化は頓挫したしな)。

言語標準ライブラリに2D描画ライブラリがあるか、十分メンテされてユーザーが居る2Dライブラリがあることが望ましいですね。

コンパイルしなくていい

コンパイルはなれている人でもやっぱり面倒だと思います。もちろんいろいろ自動化することは出来ますが、自動化を組むのが今度は面倒です。

ちなみに面倒くさがれない人は多分プログラミングにあまり向いていません。

言語規格が少なくとも5年以内に更新されている

プログラミング言語も切磋琢磨し日々様々な改善がなされているべきです。ある程度保守的なC++ですら3年おきに更新しているんですから5年経っても更新されない言語は死んでます。え?C言語?2017年末にC11と全く同じ内容をリネームして出してたけどあれはないでしょ。

言語規格が後方互換性を備えていること

初心者が頑張ってググって出てきた情報どおりに書いて動かそうとしたら動かないとなるとモチベーションが吹き飛びます。初心者じゃなくても心が折れます。セキュリティ上の懸念などからdeprecatedになる機能が出るのは仕方ないとしても、Pythonみたいに巨大なbreaking changeを噛ましてくる言語はおすすめできません。

日本語資料が豊富にあること

ただでさえわからないプログラミング言語を学ぶのに、自分の母国語じゃない資料で勉強するとか脳みそがパンクしてしまいます。

非力なPCでも開発できる

プログラミングするのに15万超えるようなPC買えと言われても多くの人は困ってしまいます。Unityとかは結構メモリー持っていくのでつらそうです。一般に出回っているPCはメモリーが4GBのものが多いです。

おすすめしたい言語

これらを満たす言語を残念ながら私の狭い知識では一つしか上げることが出来ませんでした。

JavaScript

ブラウザ上で動くのがやっぱり大きいです。Canvas APIを叩くことで図形が描画できます。実行環境をブラウザにすることで、ChromeかFirefoxを入れてもらえば(運が良ければすでに入っている)ほぼセットアップが終わります。
そのままのJavaScriptを使ったブロックくずしゲーム - ゲーム開発 | MDN
というStep-by-StepでCanvas APIを使う資料がなんとMDNにありますし実に良いです。

言語の人口も計算不能なレベルで大きく、開発も盛んです。

おすすめしたかった言語

Ruby

Ruby自体はかなりいい言語で、日本語資料も開発者が日本人ですからたくさんあります。グラフィックではRuby2dが結構良さそうなライブラリなんですよね、動けば。うごけー。

おすすめできない言語の例

C++

C++erが言うんだから間違いない(確信)。Visual Studioはコンソールアプリケーションを作る分には手順を簡単にしてくれますが、外部ライブラリを使うには不向きです。外部ライブラリをまともに使うにはCMakeという別の言語の助けが必要になります。ものすごく難しいってわけではないですが、他の言語より難しいのは確かです。

C++自体もC++17以降を使う分には極端に難しいということはないと思うのですが(C++er基準)、何分古い情報が多いのとまともな入門書がないのが辛い気がします。

グラフィックライブラリ自体はopennframeworksとかDXライブラリとかがあります。

C#

Unityはゲーム業界でもっとも使われているライブラリです。これはC#で書くことが出来ますが、Unityで使えるC#のバージョンがものすごく古いという問題がありました。ようやく新しいC#への追従の動きが一昨年くらいからあるわけですが果たしてC#の進化に追いつけるのか・・・?

C#自体はC#7.0とかC#8.0で書く分には悪くないと思いますが古い情報に出くわしやすい印象です。

Java

広く使われている言語で進化を続けています。が!Oracle JDK vs OpenJDK問題を経て(Oracle) JDK8で止まる勢とOpenJDKに移る勢で分裂している気がします。おなじくJVMで動く言語ScalaのドキュメントにはJDK8をいれろって書いてあります。C++erとしては言語そのものよりJVMレベルのゴタゴタが気になってしまいます。

ちなみにOpenJDKは自分でPATH通さないといけない問題はchocolatey使えやって思ってます。

2Dグラフィックは言語標準ライブラリにある気がします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

<<メソッド (Ruby 配列オブジェクト 要素追加 )

生成した配列オブジェクトに新しい要素を追加するときは << メソッドを使って、追加ができる

配列オブジェクト << 追加する要素

  food_case = ["穀物", "野菜", "肉"]
  food_case << "果物"
  puts food_case

<< メソッドで追加すると配列の一番最後にその要素が追加される

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Strong Paramertersについてまとめてみた

はじめに

Railsで開発をする際に、セキュリティを高める方法のひとつとしてStrong Patamertersがあります。今回はStrong Patamertersの使い方について調べてみました。間違っている部分ありましたらご指摘いただければと思います。

Strong Patamertersとは

モデルの便利な機能に、複数の属性を一括代入できる機能があります。例えば次のようなコードではUserオブジェクトを生成する際に、nameとemailという2つの属性値を一括で代入しています。

Railsコンソール
> user = User.new(name: '田中太郎', email: 'taroutanaka@gmail.com')

もしこの機能がなければ、

Railsコンソール
> user = User.new
> user.name = '田中太郎'
> user.email = 'taroutanaka@gmail.com'

と書く必要があるので少々面倒ですね。

またコントローラーで受け取ったパラメーターの一部を次のように直接モデルに渡して複数の属性を一括で取り出すこともできます。

Railsコンソール
> user = User.new(params[:user])

しかしここにセキュリティ上の危険が潜んでいます。パラメーターに意図せぬ属性が紛れ込んでいるときに、想定外の属性についても登録・更新が行えてしまう問題が生じます。

例えば、Userには有料ユーザーか無料ユーザーを判別するpremiumフラグを持っているとします。このような場合、有料ユーザーでなくてもサーバーに送るリクエスト・パラメーターを加工して、premiumフラグが無課金になるようなリクエストを送ることが技術的には可能です。

これを防ぐためにはパラメーターのどの属性を許可してどの属性を許可しないのかを制御する必要があります。この時に利用できるのがStrong Parametersという機能です。

コントローラーファイル
user_params = if user.premium
  #specialは有料ユーザーのみ使える
  params.require(:user).permit(:name, :email, :special)
else
  params.require(:user).permit(:name, :email)

User.new(user_parmas)

これで許可しない属性情報を無視することができます。

おわりに

Raislには様々なセキュリティを高める機能が用意されています。開発者側がセキュリティを高める方法を理解し、安心して使えるサービスを作る必要がると思います。今後も勉強を続けて行きたいと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pryの結果を保存して再実行したい気分

なにこれ

pryの結果をファイルに保持し、再度実行することができる。
再実行後は変数に値が入るため、複雑な処理を必要とするデバッグの際に手順をファイル化しておくことが可能。

手順

スクリプト配置

このスクリプトをプロジェクト直下またはホームディレクトリの .pryrc に配置する

記録

[1] pry(main)> ReRe.start
20190727021128.rb
=> :dubbing
[2] pry(main)> p 1111
1111
=> 1111
[3] pry(main)> user = User.first
=> #<User:0x00007fda
...
[4] pry(main)> ReRe.stop
[5] pry(main)> exit

実行

[1] pry(main)> ReRe.playback("20190727021128.rb")
run command... 
[2] pry(main)> user
=> #<User:0x00007fda
...
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pryのコマンドを保存して再実行したい気分

なにこれ

pryのコマンドをファイルに保持し、再度実行することができる。
再実行後は変数に値が入るため、複雑な処理を必要とするデバッグの際に手順をファイル化しておくことが可能。

手順

スクリプト配置

このスクリプトをプロジェクト直下またはホームディレクトリの .pryrc に配置する

記録

[1] pry(main)> ReRe.start
20190727021128.rb
=> :dubbing
[2] pry(main)> p 1111
1111
=> 1111
[3] pry(main)> user = User.first
=> #<User:0x00007fda
...
[4] pry(main)> ReRe.stop
[5] pry(main)> exit

実行

[1] pry(main)> ReRe.playback("20190727021128.rb")
run command... 
[2] pry(main)> user
=> #<User:0x00007fda
...

ファイル保存先

実行ディレクトリ以下の tmp/rere/*.rb

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rubyのシンタックス勉強用(シンボルとハッシュ 編)

Rubyのシンタックスを息を吸うように書くために、少しでも理解が怪しいシンタックスを繰り返したくために書きます。

シンボル編とハッシュ編があるので、基礎がないならこちらも見たほうがいいです。

前提知識

  • ハッシュのkeyは、同じデータ型にする必要はない。混乱の原因なので基本は揃えたほうがいい
  • ただ、valueは異なるデータ型が入る可能性がある

メソッドのキーワード引数とハッシュ

例えば、以下のようなメソッドがあったとしよう。

Harder かつ Better かつ Faster かつ Stronger であれば以下URLにある曲がリリースできるdaftpunkメソッドがあったとしよう。

https://youtu.be/GDpmVUEjagg

def daftpunk(hard, good, fast, strong)
  if hard && good && fast && strong
    puts 'release'
  else
    puts 'not release'
  end
end

daftpunk(true,true,true,true)
=> release

メソッドの引数の中身を見れば、どんな意図のメソッドかがわかるけど、以下のメソッドの呼び出しだけ見たら、よくわからないかと思います。

daftpunk(true,true,true,false)
=> not release

そんな時に使うのがキーワード引数というやつです。

引数がtrue,falseだけの時よりも、だいぶ可読性がいいのではないでしょうか?

キーワード引数を持つメソッドを呼び出す場合は、ハッシュを作成した時と同じくシンボルkey: valueの形式で引数を指定します。

def daftpunk(harder: true, better: true, faster: true, stronger: true)
  if harder && better && faster && stronger
    puts 'release'
  else
    puts 'not release'
  end
end


daftpunk(harder: true, better: true, faster: true, stronger: true)
=> release

# デフォルト引数は省略可能
daftpunk
=> release

# デフォルト引数は順番を入れ替えることも可能
daftpunk(better: true, faster: true, stronger: true, harder: false)
=> not release

# 未定義なキーワード引数を指定した場合はエラーになります
daftpunk(one_more_time: true)
=> 'daftpunk': unknown keyword: one_more_time (ArgumentError)

デフォルト引数の値がない場合、メソッド呼び出す際に値を明示しないとエラーになります。

def daftpunk(harder: true, better: true, faster: true, stronger:)
  if harder && better && faster && stronger
    puts 'release'
  else
    puts 'not release'
  end
end

daftpunk(harder: true, better: true, faster: true, stronger: true)
=> release

daftpunk(harder: true, better: true, faster: true)
=> 'daftpunk': missing keyword: stronger (ArgumentError)

メソッドを呼び出す側の引数は、キーワード引数に一致するハッシュを変数に格納して、引数として渡すこともできます。

params = { harder: true, better: true, faster: true, stronger:true }

def daftpunk(harder: true, better: true, faster: true, stronger:true)
  if harder && better && faster && stronger
    puts 'release'
  else
    puts 'not release'
  end
end

daftpunk(params)
=> release

参考: プロを目指す人のためのRuby入門_156p

ハッシュでよく使うメソッド

基本的に使うハッシュは以下。

Hash_Sample
languages = { ruby: 'rails', php: 'laravel', python: 'django', }

問題1

Hash_Sampleのキーだけを配列で返してください。

正解1

languages = { ruby: 'rails', php: 'laravel', python: 'django', }

p languages.keys
=> [:ruby, :php, :python]

参考: プロを目指す人のためのRuby入門_162p

問題2

Hash_Sampleのキーだけを配列で返してください。

正解2

languages = { ruby: 'rails', php: 'laravel', python: 'django', }

p languages.values
=> ["rails", "laravel", "django"]

参考: プロを目指す人のためのRuby入門_162p

問題3

特定のキーを持っているかどうか。戻り値が TRUE / FALSE なメソッドを書いてください。
エイリアスメソッド合わせて4つあります。

正解3

languages = { ruby: 'rails', php: 'laravel', python: 'django', }

p languages.has_key?(:ruby)
p languages.key?(:php)
p languages.include?(:python)
p languages.member?(:javascript)

=> true
=> true
=> true
=> false

参考: プロを目指す人のためのRuby入門_162p

問題4

ハッシュ(変数languages)の中でハッシュ(変数others)を展開させてください。

展開させるハッシュは以下

others = { javascript: 'react', java: 'struts' }

正解4

others = { javascript: 'react', java: 'struts' }
languages = { ruby: 'rails', php: 'laravel', python: 'django', **others }
p languages

=> {:ruby=>"rails", :php=>"laravel", :python=>"django", :javascript=>"react", :java=>"struts"}

参考: プロを目指す人のためのRuby入門_163p

問題5

擬似キーワード引数

others = { javascript: 'react', java: 'struts' }

正解5

others = { javascript: 'react', java: 'struts' }
languages = { ruby: 'rails', php: 'laravel', python: 'django', **others }
p languages

=> {:ruby=>"rails", :php=>"laravel", :python=>"django", :javascript=>"react", :java=>"struts"}

参考: プロを目指す人のためのRuby入門_163p

問題6

ハンバーガーの注文系のメソッドorder_hamburgerメソッドの引数に、

店内で食べるか(For_Here)、外で食べるか(To_Go)を指定して、

それ以外は、擬似キーワード引数にして、トマトやチーズのトッピングが必要か不要かをメソッド呼び出しで指定できるようにしてください。

擬似キーワード引数の参考 (プロを目指す人のためのRuby入門_163p

return 例

"For_Here"
"with ONION"
"with TOMATO"
"with CHEESE"

正解6

def order_hamburger( where, toppings={} )
  p "#{where}"
  p 'with ONION' if toppings.key?(:onion)
  p 'with TOMATO' if toppings.key?(:tomato)
  p 'with CHEESE' if toppings.key?(:cheese)
end

order_hamburger( 'For_Here', onion: true, tomato: true, cheese: true, )

キーワード引数を使う場合と比較すると、存在しないkeyを指定するとエラーが発生するが、類似キーワード引数は、ハッシュなので、どれだけ渡してもエラーが起こりません。
ただ、お仕事での実装は、普通のキーワード引数を使った方がよさそうです。

プロを目指す人のためのRuby入門_164p

問題7

キーワード引数に定義されていないキーワードを渡すとエラーになります。

def order_hamburger( where, onion: true, tomato: true )
  p "eat at #{where}"
end

order_hamburger( 'For_Here', onion: true, tomato: true, cheese: true, )

=> 'order_hamburger': unknown keyword: cheese (ArgumentError)

これが、どんなキーワードでも受け入れてくれるように書いてください。キーワード(cheese)を受け入れてください。

return 例

"eat at For_Here {:onion=>true, :tomato=>true, :cheese=>true}"

正解7

def order_hamburger( where, **toppings )
  p "eat at #{where} #{toppings}"
end

order_hamburger( 'For_Here', onion: true, tomato: true, cheese: true, )

プロを目指す人のためのRuby入門_164p

ハッシュから配列へ変換、配列からハッシュ変換

Hashオブジェクトに対して、to_aメソッドで配列に変換できます。その際、keyvalueの組み合わせが1つの配列になり、その配列が複数の要素としてあり、それをさらに配列としてくくっている多次元な配列になります。

languages = { ruby: 'rails', php: 'laravel', python: 'django', }

p languages.to_a
=> [[:ruby, "rails"], [:php, "laravel"], [:python, "django"]]

逆に、Arrayオブジェクトに対して、to_hメソッドで配列をハッシュに変換できます。

languages = { ruby: 'rails', php: 'laravel', python: 'django', }

p languages.to_a
=> [[:ruby, "rails"], [:php, "laravel"], [:python, "django"]]

p languages.to_h
=> {:ruby=>"rails", :php=>"laravel", :python=>"django"}

to_hメソッドで配列をハッシュに変換できますが、keyvalueの組み合わせが1つの配列になっていて、その配列が複数の要素としてなどの形式が揃っていないとエラーになります。

langs = ['ruby', 'rails', 'php', 'laravel', 'python', 'django']

p langs.to_h
=> 'to_h': wrong element type String at 0 (expected array) (TypeError)

to_hメソッドで変換できても、keyが重複した場合は、最後の要素がハッシュの要素になります。key重複はない方が望ましいです。

langs = [[:ruby, "rails"], [:php, "laravel"], [:python, "django"], [:ruby, "ruby on rails"]]

p langs.to_h
=> {:ruby=>"ruby on rails", :php=>"laravel", :python=>"django"}
# [:ruby, "rails"] の要素が亡くなっていますね

プロを目指す人のためのRuby入門_167p

ハッシュの値

ハッシュに、存在しないkeyを指定してもnilが返ります。

hash = {}
p hash[:test] # => nil

nil、以外の値を返したい場合は、Hash.new()の引数に初期値を設定すればできます。

languages = Hash.new('something')
p languages[:ruby]   # => "something"
p languages[:php]    # => "something"
p languages[:python] # => "something"
p languages[:ruby].object_id   # => 70138707695000
p languages[:php].object_id    # => 70138707695000
p languages[:python].object_id # => 70138707695000

ただし、注意が必要なのは、上を見てもわかる通り、何回呼び出しても同じ初期値が返ります。なので、初期値に対して、破壊的な変更をすると、呼び出してるやつ全部に影響があります。

その問題を解決する方法としては、ブロック引数として初期値を設定すると、ここの要素はいミュータブルなオブジェクトになります。

languages = Hash.new { 'something' }
p languages[:ruby]   # => "something"
p languages[:php]    # => "something"
p languages[:python] # => "something"
p languages[:ruby].object_id   # => 70174736763180
p languages[:php].object_id    # => 70174736762900
p languages[:python].object_id # => 70174736763180

プロを目指す人のためのRuby入門_168p

シンボルを作成する方法

エラーになるシンボルの作成方法

こんな場合はエラーになります。

  • 数字で始まる
  • ハイフンがある
  • スペースがある
p :123           # => syntax error
p :ruby-on-rails # => syntax error
p :ruby on rails # => syntax error

上記も、シングルクオートで囲むとエラーになりません。シンボルとして認識されます。

p :'123'
p :'ruby-on-rails'
p :'ruby on rails'

%記法でシンボルを複数宣言

p %i(ruby php python)
=> [:ruby, :php, :python]

プロを目指す人のためのRuby入門_170p

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gemをインストールした後にエラーになったら

gemをインストールした後にエラーになったら

RubyonRailsで開発中、上記のようになった場合・・・

結論:サーバーを再起動しましょう!!!!!!(自戒)

erbをhamlに変換しようと、

gem 'haml-rails'
gem 'erb2haml'

をgemfileに追加し、

rake haml:replace_erbs

をした後、ビューを開くと、ActionController Missingtempleteエラーに

gemをinstallした後は必ずサーバー再起動しましょう!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む