Class Level inheritable attributes - are we there yet?

D

Dreamcat Four

Hi,
Before answering to Roberts specific questions, as the OP i'd like to
show the 'common sense' analogy from an outsiders perspective. This
analogy is of real-life taxonomy, and real darwinian evolution. Its sort
of 'how nature would do it'.

So a class is the species of animal.
An instance object is an individual animal that has been born, and is
living.

The sub-species (subclass) will inherit everything and permutate /
mutate the ancestor class.
An object instance can inherit all of the same. The difference is that a
species doesn't individually live many lives, it is 'a model instance'.
Wheras an object instance is free to lead any kind of a life, and there
may be many permutations of such.

The species are in evolution are generally minimal. (you only get new
ones when they are peoperly justified). There can be many objects, but
comparatively few species.

One species of centipide has 5 body segments and 10 legs
All instances of that species also has 5 body segments and 10 legs
They also have common behaviours (methods) such as running, twisting,
etc.

A new sub-species (subclass) is formed which has [6 seg, 12 legs]. But
it still has 5 eyes, 1 mouth, and so on. These are inherited values. The
new species can't correctly execute its inherited methods {run and
twist} if its body mechanism (when derived) always ever inherits a
default number of 0 arms, 0 legs, 0 body segments, and 0 everything
else.

1) So above is the 'common sense' paradigm. (actually i originally was
asking around for). So clearly meaning its requiring deep-copy. But
because we are talking about classes and not object then there should be
much fewer of declared in your program.

2) To share same attribute amongst classes (with rubys default shallow
copy) are generally helpful for certain global constant etc in a library
environment. (myself didn't ask for that but its clearly both variation
are needed).

3) When in ruby we instantiate an object, we don't always want to copy
these same attributes above (1 and 2) into the instance. (whether or not
they are type 1 or 2 doesn't matter). Reason: not want to deep-copy
excessively because we can have many instance object (which may or may
not use the class attribute). For example, think of the lazy centipede.
It wants to {twist and wriggle}, but can't be bothered to run, so it
doesn't hardly ever use its legs. So if we chopped the legs off, it
wouldn't matter for the most part.


Robert said:
2009/10/13 ara.t.howard <[email protected]>:
OK, let's start over. For that first I would like to understand what
the problem actually is that needs to be solved here. There are many
aspects to this and I would love to see something like a requirements
list which particularly states the problem. Questions I have in mind:

- Do those attributes need to change or are they set once (quasi /
real constant)?

Yes, they need to be able to change and be any regular ruby object.
As per case 1)
- If a subclass inherits a value from the superclass is it supposed to
inherit changes to the value as well?

No for 1), yes for 2)
- What happens if a super class has its attribute unset? You might
want to retain all sub class values - or not.

Thats the same answer as the previous question.
- What happens if a super class has its attribute set? You might want
to override all sub class values at this moment.

Thats also the same answer as per the previous question.
Or i dont understand these questions.
- Must modules along the inheritance chain get their own values or is
the feature in question restricted to class instances? (Note, it's
almost impossible to include modules here because they may be part of
multiple inheritance chains.)

We don't want any polymorphic behaviour because it doesn't fit right
with natural evolution. In nature you can't cross a horse species with a
duck species to have a flying horse eh?
- Is the feature expected to work with different combinations to the
questions above.

Yes.
Its important to cover the fewest number of cases, and ensure a clear
differentiation between them. Im not 100% sure that fattr.rb syntax is
the best / most readable.


And also before we implement a solution, i hope also we can work out a
good clear syntax and do good example usages beforehand. Find the best
(to the end user) presentation so to show clearly and differentiate
between them. Otherwise it could be very unfriendly / confusing.

Options
* Whether it be a special character(like@), a special symbol :)sym),
* Wrapped in class << self (or not)
* Some accessor definition with argument
* Or some opt-in list, where must reference / redeclare attribute a
second time.
* any other diy DSL syntax, as long as it has merit



Best regards,

dreamcat4
(e-mail address removed)
 
T

Tom Stuart

One species of centipide has 5 body segments and 10 legs
All instances of that species also has 5 body segments and 10 legs
They also have common behaviours (methods) such as running, twisting,
etc.

A new sub-species (subclass) is formed which has [6 seg, 12 legs]. But
it still has 5 eyes, 1 mouth, and so on. These are inherited values. The
new species can't correctly execute its inherited methods {run and
twist} if its body mechanism (when derived) always ever inherits a
default number of 0 arms, 0 legs, 0 body segments, and 0 everything
else.

Isn't this covered by the below? Not sure how class level attributes
would give an advantage in this case.

class Centipede
def initialize
@body_segments = 5
@legs = 10
@eyes = 5
# etc
end
end

class LongerCentipede < Centipede
def initialize
super
@body_segments = 6
@legs = 12
end
end
 
D

David A. Black


I was responding to your comments about this being re-invented
repeatedly, which is not what I had been recommending. I wanted to
make that clear.
the OP simply asked why a useful idiom wasn't supported in core, which
includes it's libraries. he very clearly asked for "the best solution
in use." the subsequent posts responded as to why we shouldn't change
the language, which was never suggested, and a critique of the of the
example code, which was never asked for.

the implication was quite clear: that there isn't a best practice and
that solution should be typed out by hand since "you can make what are
essentially language-level-like constructs from a few lines of code in
Ruby"

But *not* typed out by hand anew every time they're going to be used.
The operative word in my statement was "anew".
honestly, if you read the thread start to finish, i do not think the
OP's question was given due consideration and i also think his intent
was co-opted into a request for a language change.

The beginning of the first post is:

I'm a bit puzzled by what you're saying. It would never occur to me to
"co-opt" a question. But let's move on.
i'm simply requesting that the group focus on a good, concrete,
solution for a hard problem instead of simply telling people that the
issue is so easy that it's not even worth solving.

i'd love to see some thinking about the various attempts at a complete
solution. the OP has already noted that the most common are flawed
for even moderately complex use cases, maybe the collective can narrow
in on, and even improve upon, the better ones. i've personally spent
a week or two trying to solve this problem in the general case and
have found it profoundly slippery to get right. i've already posted
my attempt at a minimal but complete solution (fattr) but would love
to hear some legitimate and thoughtful analysis of other approaches.
if a particular solution could gain some momentum as being best
practice it would a big help for the next generation of ruby
programmers - so much so that an RCR, or whatever they are called
these days, might really be in order.

Coming at it from the other angle, I'd be interested in seeing more
use cases -- not that there aren't some around, but most of the ones
I've seen seem to lend themselves to relatively simple solutions. That
probably means I haven't looked at the right ones....


David

--
The Ruby training with D. Black, G. Brown, J.McAnally
Compleat Jan 22-23, 2010, Tampa, FL
Rubyist http://www.thecompleatrubyist.com

David A. Black/Ruby Power and Light, LLC (http://www.rubypal.com)
 
D

Dreamcat Four

Tom said:
Isn't this covered by the below? Not sure how class level attributes
would give an advantage in this case.

Writing the analogy out in Ruby isn't much help here. The construct you
are showing is just the familiar method-based and pattern is a method
for performance reasons that you should prefer it. We don't argue that
point.

However by employing such the constructor chain, the species/class
definition is entirely static and not part of it can ever change. Its
brittle and fragile, and cannot adjust to / survive with changing
conditions in its environment. Of to put it another way - you cannot
append or overload a constructor funtion at runtime without destroying
entirely destroying the original constructor definition.


In Ruby, a class is defined as an object and therefore is free to change
its attributes over time. So there's no barrier in the Ruby language to
say "you must define your attributes wholely in the constructor and only
ever in the constructor function".


The real problem we are trying to address is that for the Library
writer, who will write a library of objects that behind it shall use the
constructor paradigm for many thing. But there are just a few things
which are sitting behind that in some stateful resource. (and are used
by, say 60% all object). To represent some stateful resource (endpoint
which may or may not exist) in such a brittle and inflexible way is
problematic. Essentially the constructor paradigm forces you to return
to method-based and functionally - oriented solutions.

Think about an microprocessor board, which has 5 type of io
communications port. Lets say these are RS232, USB1, USB2, LPT, and
Bluetooth. Now do you represent those as a collection of 5 sets of
methods? or as 5 stateful io_port objects?

5 io_port objects, right? But in your constructor, you would have to
call another method elsewhere to query which ports existed in the middle
of runtime. With a class attribute, you wouldn't. The appropriate
resource method would be called once only (when the library was first
loaded into memory and the port object instantiated).

Thats a 'too clean' and over-simplified example. Things actually are
much more tricky than that in real libraries. The paradigm also holds
true for many different types of resource used by a library.

Just look at Apple's cocoa frameworks. IOKit, AppKit and such. They
don't have class as object so instead they use something called a
singleton class in their library runtimes. Its essentially the same
thing.


dreamcat4
(e-mail address removed)
 
R

Robert Klemme

2009/10/13 Dreamcat Four said:
Before answering to Roberts specific questions, as the OP i'd like to
show the 'common sense' analogy from an outsiders perspective. This
analogy is of real-life taxonomy, and real darwinian evolution. Its sort
of 'how nature would do it'.

So a class is the species of animal.
An instance object is an individual animal that has been born, and is
living.

The sub-species (subclass) will inherit everything and permutate /
mutate the ancestor class.
An object instance can inherit all of the same. The difference is that a
species doesn't individually live many lives, it is 'a model instance'.
Wheras an object instance is free to lead any kind of a life, and there
may be many permutations of such.

The species are in evolution are generally minimal. (you only get new
ones when they are peoperly justified). There can be many objects, but
comparatively few species.

One species of centipide has 5 body segments and 10 legs
All instances of that species also has 5 body segments and 10 legs
They also have common behaviours (methods) such as running, twisting,
etc.

A new sub-species (subclass) is formed which has [6 seg, 12 legs]. But
it still has 5 eyes, 1 mouth, and so on. These are inherited values. The
new species can't correctly execute its inherited methods {run and
twist} if its body mechanism (when derived) always ever inherits a
default number of 0 arms, 0 legs, 0 body segments, and 0 everything
else.

This is a classical case I would resolve with instance methods that
return constant values because the information is not needed at class
level but at instance level. So we get

class Centipide
def mouths; 1 end
def eyes; 5; end
def body_segments; 5 end
def legs; 10 end

def run
puts "opening my #{eyes} eyes and starting to move"

legs.times do |i|
puts "moving leg #{i}"
end
end
end

class SubCenti < Centipide
def body_segments; 5 end
def legs; 10 end
end

Strictly speaking the class does not have segments, legs etc. - only
instances have. The scheme with instance methods can be kept even if
you provide for individual (i.e. per object) values by providing a
default via constant methods similar to those shown above.
1) So above is the 'common sense' paradigm. (actually i originally was
asking around for). So clearly meaning its requiring deep-copy. But
because we are talking about classes and not object then there should be
much fewer of declared in your program.

Btw, deep copy is usually used in the context of copying object
graphs. If I understand you correctly you mean something else
(inheriting values through hierarchies).
2) To share same attribute amongst classes (with rubys default shallow
copy) are generally helpful for certain global constant etc in a library
environment. (myself didn't ask for that but its clearly both variation
are needed).

Again, shallow copy seems to be a misnomer here.
3) When in ruby we instantiate an object, we don't always want to copy
these same attributes above (1 and 2) into the instance. (whether or not
they are type 1 or 2 doesn't matter). Reason: not want to deep-copy
excessively because we can have many instance object (which may or may
not use the class attribute). For example, think of the lazy centipede.
It wants to {twist and wriggle}, but can't be bothered to run, so it
doesn't hardly ever use its legs. So if we chopped the legs off, it
wouldn't matter for the most part.
:)



Yes, they need to be able to change and be any regular ruby object.
As per case 1)


No for 1), yes for 2)


Thats the same answer as the previous question.


Thats also the same answer as per the previous question.
Or i dont understand these questions.


We don't want any polymorphic behaviour because it doesn't fit right
with natural evolution. In nature you can't cross a horse species with a
duck species to have a flying horse eh?

But you can have duck typing! ;-)
Yes.
Its important to cover the fewest number of cases, and ensure a clear
differentiation between them. Im not 100% sure that fattr.rb syntax is
the best / most readable.

My understanding of the above is this. You have two use cases in mind:

1. Inheriting dynamic attribute values defining a proximity rule, i.e.
when asked you get the closest attribute.

2. Constants which with the same proximity lookup rule as above only
that values do not change after the initialization.
And also before we implement a solution, i hope also we can work out a
good clear syntax and do good example usages beforehand. Find the best
(to the end user) presentation so to show clearly and differentiate
between them. Otherwise it could be very unfriendly / confusing.

Yes, although the syntax could be viewed as part of the solution.
Before promoting something to the standard library I would also like
to know how much use cases there are. In other words if (unlikely
worst case) you and Ara would be the only once that have a need for
this then I'd vote for not including in the std lib.

Right now I have two issues:

1. I still have not seen a use case which would cry for a library
solution which is not there yet (see above). (I still need to ponder
the board example in your other email.)

2. It seems there are not many people wanting this (yet) - which might
well be caused by the fact that I don't read every single posting to
ruby-talk. I do have a feeling though that if there was massive
demand for this we would see it in the std lib by now.

Kind regards

robert


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

Robert Klemme

2009/10/13 Dreamcat Four said:
Writing the analogy out in Ruby isn't much help here. The construct you
are showing is just the familiar method-based and pattern is a method
for performance reasons that you should prefer it. We don't argue that
point.

However by employing such the constructor chain, the species/class
definition is entirely static and not part of it can ever change. Its
brittle and fragile, and cannot adjust to / survive with changing
conditions in its environment. Of to put it another way - you cannot
append or overload a constructor funtion at runtime without destroying
entirely destroying the original constructor definition.


In Ruby, a class is defined as an object and therefore is free to change
its attributes over time. So there's no barrier in the Ruby language to
say "you must define your attributes wholely in the constructor and only
ever in the constructor function".


The real problem we are trying to address is that for the Library
writer, who will write a library of objects that behind it shall use the
constructor paradigm for many thing. But there are just a few things
which are sitting behind that in some stateful resource. (and are used
by, say 60% all object). To represent some stateful resource (endpoint
which may or may not exist) in such a brittle and inflexible way is
problematic. Essentially the constructor paradigm forces you to return
to method-based and functionally - oriented solutions.

Think about an microprocessor board, which has 5 type of io
communications port. Lets say these are RS232, USB1, USB2, LPT, and
Bluetooth. Now do you represent those as a collection of 5 sets of
methods? or as 5 stateful io_port objects?

5 io_port objects, right? But in your constructor, you would have to
call another method elsewhere to query which ports existed in the middle
of runtime. With a class attribute, you wouldn't. The appropriate
resource method would be called once only (when the library was first
loaded into memory and the port object instantiated).

Erm, aren't you mixing class and instance state here? If you have a
Board class then that does not have any IO port objects, only
instances have - and there would be IO port classes. Each board
instance needs its own IO port objects because only those instances
can be connected with a cable to some other port. This means, the
constructor of Board would instantiate all the port instances. And
this would be done in a regular instance method (#initialize).

If you have variants of your Board then it depends on the application
design. You might have multiple Board classes (one for each variant)
which would create a different number of port objects each. Or you
might provide some arguments to the constructor which would allow for
variations.

You could even store IO port classes per Board class and subclasses
and provide initialization code which handles it, e.g.

class Board
IO_PORT_TYPES = [IOP1, IOP2]

def initialize
@io_ports = self.class::IO_PORT_TYPES.map {|cl| cl.new}
end
end

class FooBoard < Board
IO_PORT_TYPES = [IOP1, IOP2, IOP3]
end

irb(main):015:0> Board.new
=> #<Board:0x101209fc @io_ports=[#<IOP1:0x101209d4>, #<IOP2:0x101209c0>]>
irb(main):016:0> FooBoard.new
=> #<FooBoard:0x101013cc @io_ports=[#<IOP1:0x101013a4>,
#<IOP2:0x1010137c>, #<IOP3:0x10101368>]>

You can even change those arrays of classes at runtime and thus have
the dynamic behavior - and inheritance because that is taken care of
by Ruby's constant lookup mechanism.
Thats a 'too clean' and over-simplified example. Things actually are
much more tricky than that in real libraries. The paradigm also holds
true for many different types of resource used by a library.

But this is a problem. As long as we do not get to the meat of the
real problem you are trying to solve we cannot come up with a
solution. It seems you have something in your mind but I for my part
cannot claim that I fully understood what that is. Without that
understanding it's difficult to have a discussion about this. I do
not see a realistic use case which demands for class instance
variables plus inheritance and which cannot easily be covered by
existing mechanisms.

Kind regards

robert
 
D

Dreamcat Four

Robert said:
My understanding of the above is this. You have two use cases in mind:

1. Inheriting dynamic attribute values defining a proximity rule, i.e.
when asked you get the closest attribute.

Yes. I have been using this way for the YamlDoc Gem
2. Constants which with the same proximity lookup rule as above only
that values do not change after the initialization.

No. I dont suggest that.
Before promoting something to the standard library I would also like
to know how much use cases there are. In other words if (unlikely
worst case) you and Ara would be the only once that have a need for
this then I'd vote for not including in the std lib.

Right now I have two issues:

1. I still have not seen a use case which would cry for a library
solution which is not there yet (see above). (I still need to ponder
the board example in your other email.)

Its more that people generally know about @@ and expect it to be
correctly implemented.
2. It seems there are not many people wanting this (yet) - which might
well be caused by the fact that I don't read every single posting to
ruby-talk. I do have a feeling though that if there was massive
demand for this we would see it in the std lib by now.

It honestly doesn't bother me that its not in Ruby StdLib because we all
know that @@ is completely broken. And when new people learn the ruby
language they are typically faced at some point with a blog post saying
'dont use @@' because... Most people just gloss over that to go on and
learn about blocks, modules, and such constructs in Ruby.

In regards to demand for a clia_attr and to be a stand-in for @@...

Its comparatively harder for people to understand and use effectively
until they can have something better in their hand. So if others can
think up better declaration / semantics, syntax, well thats allright
then.

For the implementation part (for native ruby) I am just continuing with
what's presently in YamlDoc Gem. Based from David Black's code in post
#2. It seems the best one. I don't see what the others a bringing to the
table here.


Best Regards

dreamcat4
(e-mail address removed)
 
R

Robert Klemme

Yes. I have been using this way for the YamlDoc Gem


No. I dont suggest that.

Well, it _is_ in the language already.
Its more that people generally know about @@ and expect it to be
correctly implemented.

I had hoped for a more concrete use case...
It honestly doesn't bother me that its not in Ruby StdLib because we all
know that @@ is completely broken. And when new people learn the ruby
language they are typically faced at some point with a blog post saying
'dont use @@' because... Most people just gloss over that to go on and
learn about blocks, modules, and such constructs in Ruby.

In regards to demand for a clia_attr and to be a stand-in for @@...

Its comparatively harder for people to understand and use effectively
until they can have something better in their hand. So if others can
think up better declaration / semantics, syntax, well thats allright
then.

Well, there is a better tool: class instance variables. Most if not all
threads I have seen that contain class variables at some point end with
the suggestion to use class instance variables. This tells me that
there is a better tool and inheritance of those is not needed. I may be
wrong though which is why I would love to see proper use cases that
demand a new feature that is not yet present in the language or std lib.

We seem to talk a bit past each other and I get the impression that it
is in part because you leave many of the points I raised unanswered.

Regards

robert
 
N

Nathan

Well, it _is_ in the language already.

I prefer the constant way:

class A
Foo = 2
def self.foo
self::Foo
end
end
class B < A; end
class C < A
Foo = 4
end
class D < C; end
class E < D
Foo = 6
end
[A, B, C, D, E].map { |k| k.foo } # => [2, 2, 4, 4, 6]


I would vote that @@ be changed to be treated in the same way constants
are now (or even to be a getter/setter for a constant of the same
name), stored in original and looked up in the chain, that way they can
be overriden locally but don't need to be _forcefully copied_ down into
each and every class.

Deep (or any other) copy doesn't seem like a good idea at all to me.
 
A

ara.t.howard

Concluding from the complexity you attribute to the problem I assume
you can provide more of those guiding questions. =A0Once we have common
understanding what the problem is we can start to think about
solutions.

sorry i missed your post. i think my guidelines are probably
summarized most accurately here:

http://rubyquiz.com/quiz67.html

and here

http://github.com/ahoward/fattr

specifically the README and tests

the really relevant bit is that this

module M
inhertiable_attribute :x
end

class C
extend M
end

needs to do something sane. i also feel that any copying from the
parent (aka inheriting state) should be deferred untill the value is
actually referenced, otherwise very surprising things happen.

cheers.
 
R

Robert Klemme

2009/10/14 ara.t.howard said:
sorry i missed your post. =A0i think my guidelines are probably
summarized most accurately here:

http://rubyquiz.com/quiz67.html

and here

http://github.com/ahoward/fattr

specifically the README and tests

Thanks for the pointers! Now that looks quite specific. It seems
fattr is a superset of the koan list, correct?

I noticed a few things about your koans (a quite nice way to formulate
the spec btw.): in koan 8 and 9 you have two default values. It might
be easier for readers and technical validation if there would be two
different values; then there cannot be any confusion which value is
inherited where. Also, I believe tests like "assert{ (o.a =3D nil) =3D=3D
nil }" should better be rewritten as

o.a =3D nil
assert{ o.a =3D=3D nil }

Because Ruby guarantees that the assignment will always return the
rvalue which makes the original assert infallible.

09:11:41 ~$ allruby -e 'o=3D"";def o.a=3D(x) 123 end; p(o.a=3D99)'
CYGWIN_NT-5.1 padrklemme1 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
ruby 1.8.7 (2008-08-11 patchlevel 72) [i386-cygwin]
99
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-cygwin]
99
09:12:26 ~$
the really relevant bit is that this

=A0module M
=A0 =A0inhertiable_attribute :x
=A0end

=A0class C
=A0 =A0extend M
=A0end

needs to do something sane.

Sane is good, but where does insanity start? :)
=A0i also feel that any copying from the
parent (aka inheriting state) should be deferred untill the value is
actually referenced, otherwise very surprising things happen.

On first inspection I think I like the koans better than fattr which
seems like the swiss army knife of attribute definition because fattr
provides rich functionality. While this is generally a good thing,
the difference in complexity to the attr_* family of methods is
significant. If time permits I will play a bit with this to get a
better feeling. Thanks again!

Kind regards

robert

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

ara.t.howard

Thanks for the pointers! =C2=A0Now that looks quite specific. =C2=A0It se= ems
fattr is a superset of the koan list, correct?

it is. of course evolved. main evolutions involve

no namespace pollution (closures for state)
inheritance

I noticed a few things about your koans (a quite nice way to formulate
the spec btw.): in koan 8 and 9 you have two default values. =C2=A0It mig= ht
be easier for readers and technical validation if there would be two
different values; then there cannot be any confusion which value is
inherited where. =C2=A0Also, I believe tests like "assert{ (o.a =3D nil) = =3D=3D
nil }" should better be rewritten as

o.a =3D nil
assert{ o.a =3D=3D nil }

Because Ruby guarantees that the assignment will always return the
rvalue which makes the original assert infallible.

well, i'm dumb like that ;-) of course you are right.

Sane is good, but where does insanity start? :)

cd ~ahoward


;-)

On first inspection I think I like the koans better than fattr which
seems like the swiss army knife of attribute definition because fattr
provides rich functionality. =C2=A0While this is generally a good thing,
the difference in complexity to the attr_* family of methods is
significant. =C2=A0If time permits I will play a bit with this to get a
better feeling. =C2=A0Thanks again

check out the project on github: http://github.com/ahoward/fattr

--=20
-a
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top