Zugriff auf bestimmte Klassen beschränken

03/06/2011 - 11:17 von Thomas Preymesser | Report spam
Hi!

Ich möchte gerne folgendes Feature in Ruby realisieren: Ich habe eine Klasse A

class A

def initialize
# do something
end
end

und eine oder mehrere Klassen, die von A abgeleitet sind (hier X und Y)

require 'a'

class X < A
def initialize
super
# do something more for x
end
end

require 'a'

class Y < A
def initialize
super
# do something more for y
end
end

jetzt würde ich gerne den Zugriff auf Methoden (z.B. initialize) so beschrànken können, daß der Aufruf nur von festgelegten Klassen möglich ist. Ich möchte bei Klasse A beispielsweise in etwa so etwas schreiben können:

visible_to :initialize, [:X, :Y]

soll heißen, wenn initialize (oder beliebige andere Methoden) nicht aus der Liste der angegebenen Klassen heraus aufgerufen wird, soll ein Fehler ausgelöst werden, wie bei den folgenden Tests angedeutet:


require 'a'
require 'x'
require 'y'
require 'test/unit'

class TestEv < Test::Unit::TestCase
def test_ok
assert_nothing_raised(VisibilityError) {
x = X.new
y = Y.new
}
end
def test_error
assert_raise(VisibilityError) {
a = A.new
}
end
end


Wie könnte man so etwas realisieren?

Gruß,
-Thomas
 

Lesen sie die antworten

#1 Robert Klemme
03/06/2011 - 13:52 | Warnen spam
On 03.06.2011 11:17, Thomas Preymesser wrote:
Hi!

Ich möchte gerne folgendes Feature in Ruby realisieren: Ich habe eine Klasse A

class A

def initialize
# do something
end
end

und eine oder mehrere Klassen, die von A abgeleitet sind (hier X und Y)

require 'a'

class X< A
def initialize
super
# do something more for x
end
end

require 'a'

class Y< A
def initialize
super
# do something more for y
end
end


jetzt würde ich gerne den Zugriff auf Methoden (z.B. initialize) so
beschrànken können, daß der Aufruf nur von festgelegten Klassen möglich
ist. Ich möchte bei Klasse A beispielsweise in etwa so etwas schreiben
können:

visible_to :initialize, [:X, :Y]

soll heißen, wenn initialize (oder beliebige andere Methoden) nicht
aus der Liste der angegebenen Klassen heraus aufgerufen wird, soll ein
Fehler ausgelöst werden, wie bei den folgenden Tests angedeutet:



Zunàchst mal ist das etwas verdàchtig, wenn Du in die Oberklasse eine
Abhàngigkeit zu Unterklassen einbaust. Normalerweise sollte die
Abhàngigkeit immer in der anderen Richtung laufen.

require 'a'
require 'x'
require 'y'
require 'test/unit'

class TestEv< Test::Unit::TestCase
def test_ok
assert_nothing_raised(VisibilityError) {
x = X.new
y = Y.new
}
end
def test_error
assert_raise(VisibilityError) {
a = A.new
}
end
end


Wie könnte man so etwas realisieren?



Du weißt wàhrend der Konstruktion, zu welcher Klasse Deine Instanz gehört:

irb(main):001:0> class A
irb(main):002:1> def initialize; p self.class; end
irb(main):003:1> end
=> nil
irb(main):004:0> class X < A; end
=> nil
irb(main):005:0> A.new
A
=> #<A:0x1075a5fc>
irb(main):006:0> X.new
X
=> #<X:0x1075a6b0>

Das Wissen kannst Du für eine Prüfung ausnutzen. Das gleiche gilt
natürlich für andere Methoden. Du könntest ein bisschen
metaprogrammieren und eine Instanzmethode in Klasse Module einbauen, die
erst die Prüfung macht und dann die originale Methode aufruft.
Sonderlich sicher ist das allerdings nicht, denn jeder kann die Methode
überschreiben und dann ist Deine Sicherheit perdu.

Wofür brauchst Du das denn?

Ciao

robert


remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Ähnliche fragen