質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

1回答

1836閲覧

【Ruby】公開メンバへのアクセスを、特定のクラスに対して制限したい

philomagi

総合スコア267

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

インターフェース

インターフェイスという用語はハードウェア・ソフトウェアの両方に使うことができます。 一般的に、インターフェイスは内部処理の詳細を見せないように設定されます。オブジェクト指向プログラミングにおいて、インターフェイスはabstractクラスとして定義されます。

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

0クリップ

投稿2015/09/06 02:21

編集2015/09/06 02:25

あるクラスの公開メンバを、特定のクラスには公開したくない(=アクセスさせたくない)場合、Rubyではどのような方法があるのでしょうか。

JavaやC#のような静的型付け言語の場合は、以下のように、間にアクセス専用のインタフェースを挟んで解決しています。

Java

1public class Accessed implements AccessLimiter{ 2 private int _data = 100; 3 4 public int getData() { 5 return _data; 6 } 7 8 public int calc(int a, int b) { 9 return a + b + _data; 10 } 11 12 public String calcAsString(int a, int b) { 13 return (a + b + _data).toString(); 14 } 15} 16 17public interface AccessLimiter { 18 int getData(); 19 int calc(int a, int b); 20} 21 22public class Accessor { 23 private AccessLimiter _target; 24 25 public Accessor(Accesslimiter target) { 26 this._target = target; 27 } 28 29 public int[] access(int a, int b) { 30 int[] result = new int[3]; 31 result[0] = a; 32 result[1] = b; 33 result[2] = _target.calc(a, b); 34 35 return result; 36 } 37}

この場合、calcAsStringは基本的にはpublicメソッドですが、責務や関連の都合から、Accessorには公開したくない(=Accessorには利用させたくない)メソッドです。

しかし、Rubyにはインタフェースが存在しないため、同様の方法を使用できません。委譲によるAdapterパターンを使うしか無いのかな、と現在考えていますが、他に何か有用な手段はRubyに存在するのでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Accessor の initialize で渡された Accessed のインスタンの calcAsString のメソッドを上書きしてエラーが発生するようにしてしまうという方法ではダメですか?

ruby

1# coding: utf-8 2 3class Accessed 4 def initialize(data = 100) 5 @data = data 6 end 7 8 def calc(a, b) 9 a + b + @data 10 end 11 12 def calcAsString(a, b) 13 (a + b + @data).to_s 14 end 15end 16 17class Accessor 18 def initialize(target) 19 @target = target.clone 20 def @target.calcAsString(a, b) 21 fail "can not call" 22 end 23 end 24 25 def access(a, b) 26 [a, b, @target.calc(a, b)] 27 end 28 29 def method_A(a, b, accessed) 30 accessed.calcAsString(a, b) 31 end 32 33 def method_B(a, b) 34 @target.calcAsString(a, b) 35 end 36end 37 38accessed = Accessed.new 39accessor = Accessor.new(accessed) 40 41p accessed 42p accessed.calcAsString(1, 2) 43p accessor.access(10, 20) 44p accessor.method_A(10, 20, accessed) 45# => これはエラーにならない。 46 47p accessor.method_B(10, 20) 48# => 実行時にエラーになる。 49# Accessor 中の @target#calcAsStringをオーバーライドしてエラーになるようにしているので。

実行例:

$ ruby 1.rb #<Accessed:0x007ff3dc0fa190 @data=100> "103" [10, 20, 130] "130" 1.rb:21:in `calcAsString': can not call (RuntimeError) from 1.rb:34:in `method_B' from 1.rb:47:in `<main>'

投稿2015/09/06 08:11

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

philomagi

2015/09/06 12:28 編集

ご回答頂き、ありがとうございました。 このような方法があるのですね、知りませんでした。ただ、「アクセスしてはいけないメンバ」については、そもそもアクセス自体できないようにしたい(=メンバへの参照自体を禁止したい)という感覚があり、違和感を覚えてしまいます……。 動的型付けの場合は、呼び出し元の方で制限を設ける等して注意を払うしかないのでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問