<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Ruby | みんたく</title>
	<atom:link href="https://mintaku-blog.net/category/develop/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>https://mintaku-blog.net</link>
	<description>みんたくの技術ブログ</description>
	<lastBuildDate>Sun, 14 Mar 2021 03:54:58 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.0.11</generator>

<image>
	<url>https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2018/06/cropped-ipad-820272_640.jpg?fit=32%2C32&#038;ssl=1</url>
	<title>Ruby | みんたく</title>
	<link>https://mintaku-blog.net</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">144480658</site>	<item>
		<title>【Ruby】抽象的なスーパークラスについて整理する</title>
		<link>https://mintaku-blog.net/abstract-superclass/</link>
					<comments>https://mintaku-blog.net/abstract-superclass/#respond</comments>
		
		<dc:creator><![CDATA[みんたく]]></dc:creator>
		<pubDate>Sun, 03 Jan 2021 04:36:19 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[まとめ系]]></category>
		<category><![CDATA[技術本]]></category>
		<guid isPermaLink="false">https://mintaku-blog.net/?p=1821</guid>

					<description><![CDATA[<p>普段何気なく使っている技術や言葉について、表面的な知識にせず、しっかりとイメージできるまで自分なりに調べて整理し、理解するシリーズ。 抽象を見つけ、クラスを …</p>
The post <a href="https://mintaku-blog.net/abstract-superclass/">【Ruby】抽象的なスーパークラスについて整理する</a> first appeared on <a href="https://mintaku-blog.net">みんたく</a>.]]></description>
										<content:encoded><![CDATA[<p>普段何気なく使っている技術や言葉について、表面的な知識にせず、しっかりとイメージできるまで自分なりに調べて整理し、理解するシリーズ。</p>
<h2>抽象を見つけ、クラスを分ける</h2>
<p>どのようにして抽象的なスーパークラスを見つけ、抽象と具象を分けていくかを考えて整理してみます。</p>
<p>車を例に抽象を見つける方法を考えてみます。例えば、全ての車が自家用車しかないアプリケーションにおいてはクラス名はCarで問題ありませんが、自家用車とバスの2つがある場合は変わってきます。</p>
<p>自家用車とバスはどちらも車の一種であり、それぞれ共通化できる抽象と特化できる具象に分けることができます。そしてこの自家用車とバスを車が特化したものとして捉えるのは、継承のルールである凡化-特化の関係として正しいと考えます。</p>
<p>こうしてスーパークラスである車と、そのサブクラスである自家用車とバスに分けることができます。</p>
<p>&nbsp;</p>
<h2>抽象的なスーパークラスをつくる</h2>
<p>先程の継承から、以下のクラス図のようにCarがPrivateCarとBusのスーパークラスとなっています。</p>
<p><img data-attachment-id="1823" data-permalink="https://mintaku-blog.net/abstract-superclass/image1-7/" data-orig-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2021/01/image1.png?fit=1076%2C594&amp;ssl=1" data-orig-size="1076,594" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image1" data-image-description="" data-image-caption="" data-medium-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2021/01/image1.png?fit=300%2C166&amp;ssl=1" data-large-file="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2021/01/image1.png?fit=800%2C441&amp;ssl=1" loading="lazy" class="aligncenter size-large wp-image-1823" src="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2021/01/image1.png?resize=800%2C441&#038;ssl=1" alt="" width="800" height="441" srcset="https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2021/01/image1.png?resize=1024%2C565&amp;ssl=1 1024w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2021/01/image1.png?resize=300%2C166&amp;ssl=1 300w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2021/01/image1.png?resize=768%2C424&amp;ssl=1 768w, https://i0.wp.com/mintaku-blog.net/mintaku/wp-content/uploads/2021/01/image1.png?w=1076&amp;ssl=1 1076w" sizes="(max-width: 800px) 100vw, 800px" data-recalc-dims="1" /></p>
<p>この継承構造によってCarが共通の振る舞いを持ち、PrivateCarとBusがそれぞれ特化した振る舞いを追加できます。</p>
<p>以下のコードでは、スーパークラスであるCarは共通のsizeを含み、サブクラスであるBusは特有のpaymentを含みます。</p><pre class="crayon-plain-tag">class Car
  attr_reader :size

  def initialize(args={})
    @size = args[:size]
  end

end

class PrivateCar &lt; Car

  def initialize(args)
    super(args)
  end

end

class Bus &lt; Car
  attr_reader :payment_style

  def initialize(args)
    @payment_style = args[:payment_style]
    super(args)
  end

end</pre><p>&nbsp;</p>
<h2>テンプレートメソッドパターン</h2>
<p>Carのinitializeメソッドにdefault_seat_colorとdefault_seat_numberというデフォルト値となる2つのメッセージを追加してみます。</p>
<p>これらのメッセージを用意しオーバーライドすることで、サブクラスに特化した状態や振る舞いを定義する機会を与えることができます。</p>
<p>スーパークラス内で基本の構造を定義し、サブクラスにメッセージを送る手法は、テンプレートメソッドパターンとして知られています。</p>
<p>以下のコードでは、サブクラス両方ともdefault_seat_numberを実装し、default_seat_colorはスーパークラスにのみ実装しています。それぞれのサブクラスは座席数に独自の初期値を用意するものの、座席の色はスーパークラスの共通の初期値を継承します。</p><pre class="crayon-plain-tag">class Car
  attr_reader :size

  def initialize(args={})
    @size = args[:size]
    @seat_color = args[:seat_color] | default_seat_color
    @seat_number= args[:seat_number] | default_seat_number
  end

  def default_seat_color
    ‘black’
  end

end

class PrivateCar &lt; Car

  def default_seat_number
    4
  end

end

class Bus &lt; Car
  attr_reader :payment_style

  def initialize(args)
    @payment_style = args[:payment_style]
    super(args)
  end

  def default_seat_number
    24
  end

end</pre><p>これによって、全ての車において座席の色は同じ初期値が使われ、座席数はサブクラスによって異なる初期値が使われるようになりました。</p>
<p>&nbsp;</p>
<h2>全てのテンプレートメソッドを実装する</h2>
<p>Carによるinitializeメソッドではdefault_seat_numberをサブクラスに送りますが、Car自体には実装れていません。そのため例えば新しくトラックを追加した場合、以下のような問題を引き起こす場合があります。</p><pre class="crayon-plain-tag">Class Truck &lt; Car

  def default_seat_color
    ‘gray’
  end

end

truck = Truck.new(size: ‘M’)
# undefined local variable or method ‘default_seat_number’</pre><p>&nbsp;</p>
<p>これは、今後Carから新しくサブクラスを作っていくタイミングで発生しうるエラーです。この問題は一見コードを見るだけではわからない要件をサブクラスに課していることです。</p>
<p>Carにdefault_seat_numberが書かれている限り、サブクラスはdefault_seat_numberを必ず実装している必要があります。</p>
<p>この気付きにくい要件を前もって知らせるためには、テンプレートメソッドパターンを使うどのクラスにおいても、送信するメッセージの全てに実装を用意します。</p>
<p>以下のようにサブクラスがメッセージを実装する必要があるとスーパークラスに明示的に示すことで、開発者は要件に気付くことができます。例え実装時に気づかなくても明確なエラーメッセージを用意することで、実行時に開発者はそのエラーメッセージから気付くことができます。</p><pre class="crayon-plain-tag">Class Car

  …

  def default_seat_number
    raise NoImplementedError
      “This #{self.class} cannot respond to:”
  end

end</pre><p>&nbsp;</p>
<p>参考：</p>
<p><iframe loading="lazy" title="オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方" type="text/html" width="800" height="550" frameborder="0" allowfullscreen style="max-width:100%" src="https://read.amazon.com.au/kp/card?preview=inline&#038;linkCode=kpd&#038;ref_=k4w_oembed_Bk5YPqECObecyG&#038;asin=477418361X&#038;tag=kpembed-20"></iframe></p>The post <a href="https://mintaku-blog.net/abstract-superclass/">【Ruby】抽象的なスーパークラスについて整理する</a> first appeared on <a href="https://mintaku-blog.net">みんたく</a>.]]></content:encoded>
					
					<wfw:commentRss>https://mintaku-blog.net/abstract-superclass/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1821</post-id>	</item>
		<item>
		<title>ダックタイピングについて整理する</title>
		<link>https://mintaku-blog.net/about-ducktyping/</link>
					<comments>https://mintaku-blog.net/about-ducktyping/#respond</comments>
		
		<dc:creator><![CDATA[みんたく]]></dc:creator>
		<pubDate>Fri, 01 Jan 2021 02:07:09 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[まとめ系]]></category>
		<category><![CDATA[技術本]]></category>
		<guid isPermaLink="false">https://mintaku-blog.net/?p=1803</guid>

					<description><![CDATA[<p>普段何気なく使っている技術や言葉について、表面的な知識にせず、しっかりとイメージできるまで自分なりに調べて整理し、理解するシリーズ。 ダックタイピングとは  …</p>
The post <a href="https://mintaku-blog.net/about-ducktyping/">ダックタイピングについて整理する</a> first appeared on <a href="https://mintaku-blog.net">みんたく</a>.]]></description>
										<content:encoded><![CDATA[<p>普段何気なく使っている技術や言葉について、表面的な知識にせず、しっかりとイメージできるまで自分なりに調べて整理し、理解するシリーズ。</p>
<h2>ダックタイピングとは</h2>
<p>ダックタイピングとは、Rubyなどの動的型付けオブジェクト指向プログラミング言語で使われる型付けのやり方のことです。</p>
<p>この名前は「もしオブジェクトがダックのように鳴き、ダックのように歩くのならば、そのクラスが何であれ、それはダックである」と言う表現に由来しています。つまり、その何かが穴を掘ろうが、ジャンプしようが、ダックのように鳴き、歩くのであれば、それはダックとして扱うことができるということだと解釈しました。</p>
<p>実際にコードに落とし込んで考えた際、ダックタイプはどの特定のクラスとも紐付かないインタフェースを定義することになると考えました。</p>
<h2>ダックタイピングの使い所と具体例</h2>
<p>実際にRubyでダックタイピングの使い所を考えてみます。</p>
<p>具体例として特典クラスがあり、会員によって提供する特典が変わるとします。会員を引数にcase文を使って提供する特典を判定しています。</p>
<p>この状態だと、会員メンバーのランクが増える度に、case文を追加しなくてはならず、システムが複雑化していく要因になります。</p><pre class="crayon-plain-tag">class Benefit
  attr_reader :gift_certificate, :souvenir, :coupon

  def find_benefit(members)
    members.each do |member|
      case member
      when PlatinumMember
        employee.prepare_gift_certificate(gift_certificate)
      when GoldMember
        employee.prepare_souvenir(souvenir)
      when StandardMember
        employee.prepare_coupon(coupon)
    end
  end
end</pre><p>&nbsp;</p>
<p>ダックタイプを意識して設計し直すと、以下のようになります。それぞれの引数のクラスは、新しいインターフェースを実装しています。</p>
<p>また、それぞれのランククラスが応答できるfind_benefitを追加することで、オブジェクトごとに振る舞いを変えることができます。</p>
<p>このprepare_benefitメソッドは、新たにランクを追加した際でも変更されることがありません。</p><pre class="crayon-plain-tag">class Benefit
  attr_reader :gift_certificate, :souvenir, :coupon

  def prepare_benefit(members)
    members.each do |member|
      member.find_benefit(self)
    end
  end
end

class PlatinumMember
  def find_benefit(benefit)
    prepare_gift_certificate(benefit.gift_certificate)
  end
end

class GoldMember
  def find_benefit(benefit)
    prepare_souvenir(benefit.souvenir)
  end
end

class StandardMember
  def find_benefit(benefit)
    prepare_coupon(benefit.coupon)
  end
end</pre><p>&nbsp;</p>
<p>&nbsp;</p>
<h2>ダックタイピングとポリモーフィズムの関係性</h2>
<p>ダックタイピングを学んでみて、真っ先に思い浮かんだのはポリモーフィズムでした。ポリモーフィズムはあるが、ダックタイピングがないJavaなどの言語もあり、ダックタイピングはポリモーフィズムを実践するための一つの手段のように思いました。</p>
<p>実際に本記事の参考である、「オブジェクト指向設計実践ガイド」でもポリモーフィズムの話が登場し、一つの方法と説いています。</p>
<p>とはいえ、ダックタイピングとポリモーフィズムの関係性について調べていると、ポリモーフィズムはインターフェースによる明示性を必要をするものだからダック・タイピングは違うと説いている意見もあり、若干混乱しています。。</p>
<p>&nbsp;</p>
<h2>ダックタイピングというより動的型付け言語における課題点</h2>
<p>ダックタイピングを学んで、より動的型付け言語における型による実行時エラーの課題点が浮き彫りになったように思いました。</p>
<p>ダックタイピングはオブジェクト指向設計における柔軟性と変更のしやすさを高めるが、静的型付け言語のように型を明確に定義しないが故に、実行するまで型エラーに気づくことが難しい点があります。特に大規模の開発や複雑なシステムにおいて大きな障害になるのではないかと思いました。</p>
<p>&nbsp;</p>
<p>参考：</p>
<p><iframe loading="lazy" title="オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方" type="text/html" width="800" height="550" frameborder="0" allowfullscreen style="max-width:100%" src="https://read.amazon.com.au/kp/card?preview=inline&#038;linkCode=kpd&#038;ref_=k4w_oembed_kAfyKGE51CfCm4&#038;asin=477418361X&#038;tag=kpembed-20"></iframe></p>The post <a href="https://mintaku-blog.net/about-ducktyping/">ダックタイピングについて整理する</a> first appeared on <a href="https://mintaku-blog.net">みんたく</a>.]]></content:encoded>
					
					<wfw:commentRss>https://mintaku-blog.net/about-ducktyping/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1803</post-id>	</item>
		<item>
		<title>【Ruby】固定された順番の引数への依存を回避する</title>
		<link>https://mintaku-blog.net/ruby-args/</link>
					<comments>https://mintaku-blog.net/ruby-args/#respond</comments>
		
		<dc:creator><![CDATA[みんたく]]></dc:creator>
		<pubDate>Mon, 28 Dec 2020 19:41:50 +0000</pubDate>
				<category><![CDATA[Ruby]]></category>
		<guid isPermaLink="false">https://mintaku-blog.net/?p=1779</guid>

					<description><![CDATA[<p>Rubyにおいて引数が必要なメソッドを使う際に、引数についての知識や特定の固定された順番で渡す必要があり、依存関係が生まれます。この固定された順番の引数への …</p>
The post <a href="https://mintaku-blog.net/ruby-args/">【Ruby】固定された順番の引数への依存を回避する</a> first appeared on <a href="https://mintaku-blog.net">みんたく</a>.]]></description>
										<content:encoded><![CDATA[<p>Rubyにおいて引数が必要なメソッドを使う際に、引数についての知識や特定の固定された順番で渡す必要があり、依存関係が生まれます。この固定された順番の引数への依存に対して回避する方法をメモしておきます。</p>
<h2>初期化の際に引数にハッシュを使う</h2>
<p>固定されたパラメータの代わりにオプションのハッシュを受け取れるように実装します。</p>
<p>initializeメソッドは引数をただ1つのargsのみにしています。argsはハッシュであり、入力の全てが含まれます。そのため、引数の順番に対する依存が全て取り除かれ、初期化の際に使われる引数やデフォルト値の追加や削除がしやすくなります。</p><pre class="crayon-plain-tag">class Character

  attr_accessor :hp, :offensive_power, :defense_power

  def initialize(args)
    @hp = args[:hp]
    @offensive_power = args[:offensive_power]
    @defense_power = args[:defense_power]
  end
end

character = Character.new(:hp =&gt; 100, :offensive_power =&gt; 20, :defense_power =&gt; 5)</pre><p>&nbsp;</p>
<h2>||メソッドでデフォルト値を設定する</h2>
<p>||メソッドを使って明示的にデフォルト値を設定することができます。</p>
<p>注意点として、||メソッドはor演算子と同様の動作をするため、左辺の式がfalseまたはnilの場合右辺の結果を返します。</p><pre class="crayon-plain-tag">...

def initialize(args)
  @hp = args[:hp] || 50
  @offensive_power = args[:offensive_power] || 5
  @defense_power = args[:defense_power] || 2
end

...</pre><p>例えば以下のような式の場合は、boolキーが存在しない時、または存在するが値がfalseまたはnilの場合でもtrueが設定されるようになってしまいます。</p><pre class="crayon-plain-tag">@bool = args[:bool] || true</pre><p>&nbsp;</p>
<h2>fetchメソッドでデフォルト値を設定する</h2>
<p>そのため、引数のfalseとnilの区別が必要な場合はfetchメソッドをデフォルト値の設定として使うのが良さそうです。fetchメソッドは対象のキーをみつけるのに失敗しても自動的にnilを返しません。</p>
<p>以下の例の場合、fetchメソッドを使うことでhpキーがargsハッシュにない場合のみ、デフォルト値の50が設定されるようになっています。||メソッドの違いは、hpに対してfalseやnilを設定することができます。</p><pre class="crayon-plain-tag">...

def initialize(args)
  @hp = args.fetch(:hp, 50)
  @offensive_power = args.fetch(:offensive_power, 5)
  @defense_power = args.fetch(:defense_power, 2)
end

...</pre><p>&nbsp;</p>
<p>参考：<a href="https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E8%A8%AD%E8%A8%88%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-Ruby%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8B-%E9%80%B2%E5%8C%96%E3%81%97%E3%81%A4%E3%81%A5%E3%81%91%E3%82%8B%E6%9F%94%E8%BB%9F%E3%81%AA%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E8%82%B2%E3%81%A6%E6%96%B9-Sandi-Metz/dp/477418361X" target="_blank" rel="noopener">オブジェクト指向設計実践ガイド</a></p>The post <a href="https://mintaku-blog.net/ruby-args/">【Ruby】固定された順番の引数への依存を回避する</a> first appeared on <a href="https://mintaku-blog.net">みんたく</a>.]]></content:encoded>
					
					<wfw:commentRss>https://mintaku-blog.net/ruby-args/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1779</post-id>	</item>
	</channel>
</rss>
