【Rails】技術面接対策の記事の質問を多少深ぼる記事⑥
はじめに
こんにちは!大ちゃんの駆け出し技術ブログです。
この記事は前回の記事の続きものです。
(前回の記事)
本記事ではQ31 ~ Q36を深掘りします。
Q31: procとlambdaの違いを説明してください
回答:
procもlambdaも、ブロックを保存したものであるという点では同じですが、構文や振る舞いがわずかに異なります。 lambdaの中に書いたreturnはlambda自身から抜けますが、procの中に書いたreturnはそのprocを含むメソッドから抜けます。
def method_proc thing = Proc.new { return 1} thing.call return 2 end def method_lambda thing = lambda { return 1} thing.call return 2 end puts method_proc # => 1 puts method_lambda # => 2
上の
method_proc
で1
が返る点にご注目ください。これは、procを呼び出すとその時点でmethod_proc
メソッド内での実行が終了するためです。 訳注: procから値を返すにはnextを使います。参考: 手続きオブジェクトの挙動の詳細 (Ruby 2.7.0 リファレンスマニュアル)
Procとlamdaの挙動については以下の本で随分前に学習していたのですが、完全に忘れてしまったのでここでしっかり復習します!💪 💪 💪
プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで Software Design plus
Procはブロックをオブジェクト化することができるオブジェクト(クラス)のことです。ブロックはオブジェクトではありません。「Q2:「Rubyでは(ほぼ)あらゆるものがオブジェクトである」について説明してください」で説明しましたが、Rubyは全てがオブジェクトではなく、ブロックもオブジェクトではありません。しかし、ブロックをオブジェクト化することでよりブロックの利便性を拡張することができるProcが使われます。下記の例を見てみます。
proc = Proc.new { p "proc" }
Procはクラスですがインスタンスを作成するための引数はブロックとなるため、new{}でインスタンスを作成しています。procオブジェクト.call
によって渡されたオブジェクトを呼び出すことができます。
def method_proc proc = Proc.new { p "proc" } proc.call end method_proc =>"proc"
ブロックがオブジェクトであることも確認することができます。
proc = Proc.new { p "proc" } => #<Proc:0x00007fa325919ce8@(irb):3> proc.class => Proc proc.class.superclass => Object proc.class.superclass.superclass => BasicObject
lamdaについてもProc.newと同様にブロックをオブジェクト化する役割があります。
def method_lambda proc = lambda { p "proc" } proc.call end method_lambda =>"proc"
しかし、いくつか違いがあるようで、例で挙げられているのもその一つです。
Procの場合
def method_proc thing = Proc.new { return 1} thing.call return 2 end puts method_proc # => 1
lamdaの場合
def method_lambda thing = lambda { return 1} thing.call return 2 end puts method_lambda # => 2
一見同じようにブロックは定義していますが、Proc.newで作成したオブジェクトの場合、一度returnを実行するとそのメソッド自体を抜け出してしまいます。しかし、lamdaの場合、returnが実行された後も処理が実行されます。なぜこのような違いを設けたのかはわかりませんが、違いは抑えておきましょう。
Q32: Rubyのyieldについて説明してください
回答:
yieldは、メソッドに渡されたブロックにアクセスします。Railsアプリケーションのレイアウトファイルで使われるyieldが典型的です。
def puts_stuff puts 'first line' yield if block_given? puts 'third line' yield if block_given? end puts_stuff { puts 'its me' } # => first line # => its me # => third line # => its me
上のコードではyieldを呼び出したときに「its me」が出力されます。
「yieldは、メソッドに渡されたブロックにアクセスします」とあります。メソッドの中にyieldを置いてみます。
def hoge yield end
このメソッドに対してブロックを渡します。
hoge { p 'hogehoge'} => "hogehoge"
上記のように記述することで、yieldの部分がブロックの中にとって変わったということです。
def hoge yield end ↓ def hoge p 'hogehoge' end
「Railsアプリケーションのレイアウトファイルで使われるyieldが典型的です。」とありますが、Railsのapplication.html.erbでよくyieldは使われるかと思います。
<!DOCTYPE html> <html> <head> </head> <body> <%= yield %> </body> </html>
このyieldはrubyですのでこの部分にビューごとのレイアウトファイルが読み込まれていたということです。
Q33: content_forの使いみちを説明してください
回答:
content_forは、ビュー内でコンテンツを定義したりレンダリングしたりできます。これは、コンテンツを1箇所で定義してさまざまな場所でレンダリングするのに便利です。
これはQ32で説明したyieldと組み合わせて使うことが多いと思います。最もよくあるのはタイトルの表示ですね。
上記の例はアクセスページのタイトルですが、これを「Hogehoge | AAA電機」みたいにページごとに内容は変えどもその後の企業名は変えないという場合があると思います。その時にcontent_forは重宝されます。
共通レイアウトであるapplication.html.erbのheadタグ内にyield文を記載します。
<title><%= page_title(yield(:title)) %></title>
ビューをサポートするメソッドとしてヘルパーメソッドを定義します。
module ApplicationHelper def page_title(page_title = '') base_title = 'AAA 電機' page_title.empty? ? base_title : page_title + " | " + base_title end end
あとはページごとのビューファイルにcontent_forを使用することでタイトルを動的に変更します。
アクセスページ
<% content_for(:title, 'Access' ) %>
→ 「Access | AAA電機」
<% content_for(:title, 'About' ) %>
→ 「About | AAA電機」
実は前に記事を書いたことがありますのでよろしければぜひ!
Q34: HashとJSONの違いを説明してください
回答:
HashはRubyのクラスであり、キーを指定して値にアクセスできるキーバリューペアのコレクションです。 JSONは、データ送信に用いる特定のフォーマットを持つ文字列です。
「キーを指定して値にアクセスできるキーバリューペアのコレクション」とあるように、キーと値がペアとして記述されております。
hash = { "key1" => "value1", "key2" => "value2" }
キーを指定することで値を出力することができます。
p hash[:key1] => "value1"
ちなみにhash.classでHashクラスというものがあることがわかります。
hash.class
=> Hash
「JSONは、データ送信に用いる特定のフォーマットを持つ文字列」とありますが、見た目はすごくHashですね。
{ "productId": 1, "productName": "A green door", "price": 12.50, "tags": [ "home", "green" ] }
Q35: Active Jobについて説明してください
回答:
Active Jobは、バックグラウンドジョブを作成して、Delayed::JobやSidekiqといったさまざまなバックエンドにキューイングします。 Active Jobの典型的な利用法は、メインのWebスレッドで実行する必要のないコードの実行です。ユーザーにメール通知を送信するときによく使われます。
Railsガイドには以下のように説明されています。
Active Jobは、ジョブを宣言し、それによってバックエンドでさまざまな方法によるキュー操作を実行するためのフレームワークです。ジョブには、定期的なクリーンアップを始めとして、請求書発行やメール配信など、あらゆる処理がジョブになります。これらのジョブをより細かな作業単位に分割して並列実行することもできます。
ジョブというのは仕事の単位です。定期的なクリーンアップやメール配信はまさにジョブですね。
基本的にバックエンドにある時に実行して欲しいタイミングで設定をしておき、そのタイミングになったらジョブが実行されます。それぞれのジョブには実行する順番があり、その順番のことをキューと言います。
※ 反対に先入先出しのスタックというものもあります。
キューの例
https://www.sejuku.net/blog/63202
Active Jobによって上記のようにジョブをキューに入れて実行することができます。ここでは詳しい実装は省きます、、!
自分のブログ初期でも記事書いてます!
Q36: Railsのどういうところが好きですか?
回答:
私の場合は、さまざまなWebフレームワークを使ってきましたが、RailsほどMVPを短期間で構築できるものは他にありませんでした。他にも以下の点が特に気に入っています。 ・開発が楽しい。Time.now + 5.daysやobj.nil?といった書き方ができるのは幸せ。 ・コミュニティの存在がとても助けになり、サンプルやドキュメントが簡単に見つかる。 ・「設定より規約」とは、新しい巨大なコードベースに触れたときにどこを見ればいいかがわかるということ。Djangoのような設定を好む他のフレームワークと比較したときに、特にそれを感じる。
「え?まさかの主観、、、、」
この質問自分にとっては非常に答えづらい、、、、。なぜかというと初学者なのでRailsぐらいしかバックエンドの言語は使ったことがありません。ですので、どこが好きかと聞かれても他のバックエンドと比較できず、Railsが他の言語に比べて優れているところがわかりません、、、。
とりあえず回答の例を一度参考にしてみます。
- RailsほどMVPを短期間で構築できるものは他にない
これは確かに納得できます!初学者である自分でさえ、かなり短期間でアプリを作ることができたのでどれほど短期的な開発に向いているかが伺えますね、、!動的型付けではあり大規模開発で長期的な運用は他の言語が向いそうですが、短期的な開発でユーザに使ってもらうことを最優先にする開発はとっても向いていると思います。
- 開発が楽しい。Time.now + 5.daysやobj.nil?といった書き方ができるのは幸せ
納得です。Date.todayとか本当に直感でコードを書けることが多かった気がしますね。
- コミュニティの存在がとても助けになり、サンプルやドキュメントが簡単に見つかる。
日本発の言語ということもありますし、それに初学者がよく書く記事でもあるので、情報へのアクセス先が非常に多いと思いました。RailsガイドやRailsチュートリアルなど、勉強のための教材が豊富で基本的にはggれば解決しました。
参考にしたことを踏まえて個人的にRailsの好きな部分を書きたいと思います。
- Active Recordが優秀
「Q26: Active Recordについて説明してください」で説明しましたが、Rubyのメソッドを用いることでSQLと同じようにデータを操作することができるRailsの機能です。RUNTEQの講師の方もActive RecordがあるおかげでRailsが長く使われているとおっしゃっていました。おそらく他の言語でもORMのフレームワークはあると思うのですが、それでもActive Recordは優秀そうですね。
Active Recordで記述
User.find_by(name: "hogehoge")
SQLのSELECTで記述
SELECT * FROM users WHERE name = "hogehoge"
自分のポートフォリオは初学者では多い約20個のテーブルを作成したので、Active Recordには非常に救われました。
しかし、SQLを覚えなくてもいいというのは初学者にとっては大変大きなメリットですが、SQLが疎かになってしまいそうですね、、。
これは他のWeb開発におけるバックエンド言語のフレームワークでも同様の概念だと思いますが、モデル、コントローラ、ビューの構成は初学者がアプリケーションを構築する上で明確なコーディング指標になりました。
https://www.yuta-u.com/programing/rails_mvc
この図自体も最初は全く理解できませんでしたが、自分でアプリを作成していく上で理解していきました。
Model --> データとロジックを管理
Controller --> 入力を受け取り、モデルやビューに渡すデータを準備
View --> 情報を表示
Model
class Post < ApplicationRecord scope :recent, -> { order(id: :desc).limit(5) } end
Controller
class PostController < ApplicationController @recent_posts = Post.recent redirect_to posts_path end
View
<% @recent_posts.each do |post| %> <tr> <td><%= post.title %></td> <td><%= post.content %></td> </tr> <% end %>
終わりに
今回はあまり深掘りできなかったですね、、、。
今回はここまで!!!!
次回はQ37からです!