Anyone using Copland? I need feedback!

J

Jamis Buck

Copland (an IoC container for Ruby) is moving forward, and I *think*
it's almost ready to be considered at a "beta" level of stability and
usability. That said, I need feedback: is anyone here using Copland?
I've heard from (I think) two people, off list, that are using it.

What I need is (a) what features you feel are still missing, and (b)
what features you think need to be fixed.

Thanks!

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."
 
H

Hal Fulton

Jamis said:
Copland (an IoC container for Ruby) is moving forward, and I *think*
it's almost ready to be considered at a "beta" level of stability and
usability. That said, I need feedback: is anyone here using Copland?
I've heard from (I think) two people, off list, that are using it.

What I need is (a) what features you feel are still missing, and (b)
what features you think need to be fixed.

So many bright people rave about IoC that it must be something
pretty cool. But it always makes me think of _The Cat in the Hat_ --
the TV version -- where someone has stolen his purple three-handled
family gradunza, or whatever it was.

Try as I might, I can't yet grasp what it is, what it's for, or why
I might need it.

Reminds me of early 80s when I first heard of OOP -- from a person
who also didn't understand it. He gave me a sketchy outline of what
it was about, and I thought: Why? Why would I need that?

But I'll do some more reading. :) Until I grasp it, I'll just listen
to Copland instead of coding with Copland, using plain old un-inverted
control.


Hal
 
J

Jamis Buck

Hal said:
So many bright people rave about IoC that it must be something
pretty cool. But it always makes me think of _The Cat in the Hat_ --
the TV version -- where someone has stolen his purple three-handled
family gradunza, or whatever it was.

Nice metaphor! I don't think I ever saw that, but it sounds very
Seussian. :)
Try as I might, I can't yet grasp what it is, what it's for, or why
I might need it.

That's exactly where I was about a year ago, when I was first told that
we were moving to Java (like it or not), and we were going to be using
an "Inversion of Control framework". They explained it and explained it,
and never really got it until I actually starting *using* it. Then I
fell in love with it. :)
Reminds me of early 80s when I first heard of OOP -- from a person
who also didn't understand it. He gave me a sketchy outline of what
it was about, and I thought: Why? Why would I need that?

It's not quite as fundamental of a paradigm shift, but it is still
significant. Howard Lewis Ship (the creator of HiveMind, which inspired
Copland) has recently described IoC as the counterpart to garbage
collection. Just as garbage collection is responsible for automatically
reclaiming and destroying objects at the end of their lifecycle, so is
IoC responsible for creating and initializing objects at the beginning
of their lifecycle.
But I'll do some more reading. :) Until I grasp it, I'll just listen
to Copland instead of coding with Copland, using plain old un-inverted
control.

That works, too. :) Frankly, it isn't until you ramp up to some fairly
complex applications that IoC really starts to buy you anything. (The
text editors that have recently been announced have seemed in my mind
prime candidates for IoC.) And for really small projects, it can just
get in the way. It's also not something you use "ad-hoc"--it requires a
fair bit of thought and design "up-front" to really take advantage of.

Anyway--hopefully my presentation in a month will be helpful. I've
learned a lot more about the topic just preparing for it. :)

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."
 
S

Sascha Ebach

Dear Jamis,

Jamis said:
Copland (an IoC container for Ruby) is moving forward, and I *think*
it's almost ready to be considered at a "beta" level of stability and
usability. That said, I need feedback: is anyone here using Copland?
I've heard from (I think) two people, off list, that are using it.

What I need is (a) what features you feel are still missing, and (b)
what features you think need to be fixed.

I am new to the IoC/DI kind of working, but I find it _very_
interesting, although I don't actually know how to get started. The
documentation is very good so far, but only covers the basics and it
doesn't help with "getting into it" (me at least). The reason I can't
decide to use this technique is because there are no real world examples
I could look at (for Copland, I guess there are for Java DI libraries).
It really bothered me when, after enjoying the whole very nicely written
documentation, I still didn't know how exactly I could use Copland to
help in my programming. What I am saying is that I would really like
some small example app which shows the difference between using Copland
and not using it. Some good instructions. I am not asking you to write a
book, but maybe you have read Kent Becks Test Driven Development or "A
Programming Episode" in Agile Software Development by Robert C. Martin.
I would like to have some advice on "Here is how you use it".

"Ask not what I could do for Copland, ask what Copland can do for me" ;)

If it not asking too much I would really like to see 2 little sample
apps with the one where you could at least start to see the benefits in
action. I understand that the real benefits start to show when the
system is getting bigger. I would need something that would bring me
into the right mindset so I could decide to use this technique for my
programming efforts or when to use it. Does that make sense?

Using DI seems to me like a little more than just using the next
library. Maybe it is not such a big paradigm as TDD, but it seems like a
certain way of programming that needs a little more explanation than the
usual stuff. I really wonder how I could benefit from that.
 
J

Jamis Buck

Sascha said:
Dear Jamis,




I am new to the IoC/DI kind of working, but I find it _very_
interesting, although I don't actually know how to get started. The
documentation is very good so far, but only covers the basics and it
doesn't help with "getting into it" (me at least). The reason I can't
decide to use this technique is because there are no real world examples
I could look at (for Copland, I guess there are for Java DI libraries).
It really bothered me when, after enjoying the whole very nicely written
documentation, I still didn't know how exactly I could use Copland to
help in my programming. What I am saying is that I would really like
some small example app which shows the difference between using Copland
and not using it. Some good instructions. I am not asking you to write a
book, but maybe you have read Kent Becks Test Driven Development or "A
Programming Episode" in Agile Software Development by Robert C. Martin.
I would like to have some advice on "Here is how you use it".

"Ask not what I could do for Copland, ask what Copland can do for me" ;)

Very appropriate advice, Sascha. :)
If it not asking too much I would really like to see 2 little sample
apps with the one where you could at least start to see the benefits in
action. I understand that the real benefits start to show when the
system is getting bigger. I would need something that would bring me
into the right mindset so I could decide to use this technique for my
programming efforts or when to use it. Does that make sense?

Lots of sense. As I said in my reply to Hal, though, IoC really benefits
large applications more than small ones. However, the 0.6.0 release of
Copland has a "real world" example application of a Calculator
implemented using IoC. (I put "real world" in quotes, because although
it demonstrates the techniques of programming with IoC, it's not the way
you'd really want to do a trivial calculator program.)

Also, the documentation in CVS (which will be released with 0.7.0, very
soon) includes a couple more tutorials (bringing the total to 4). The
tutorials since the rewrite are, I think, much more applicable than
before--I don't know how recently you've looked at the Copland docs.

Still--I'll see if I can't think of a nice, large, "real world" example
of IoC (specifically, using Copland) and then see if I can find a good
way to present it in the documentation. Ironically, I don't have any
large examples using Copland, although I've got a couple in mind that I
keep intending to start "as soon as I'm done with Copland." ;)
Using DI seems to me like a little more than just using the next
library. Maybe it is not such a big paradigm as TDD, but it seems like a
certain way of programming that needs a little more explanation than the
usual stuff. I really wonder how I could benefit from that.

Thanks for the feedback, Sascha. I'll do some thinking, too. I'll see if
I can find a better way to present IoC.

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."
 
S

Simon Strandgaard

On Saturday 04 September 2004 22:57, Jamis Buck wrote:
[snip]
That works, too. :) Frankly, it isn't until you ramp up to some fairly
complex applications that IoC really starts to buy you anything. (The
text editors that have recently been announced have seemed in my mind
prime candidates for IoC.) And for really small projects, it can just
get in the way. It's also not something you use "ad-hoc"--it requires a
fair bit of thought and design "up-front" to really take advantage of.


Text editor.. hmm.. im working on an editor, so now you have woken my
interest. I have looked at copland + the documents you link to, but im
affraid I don't understand what it is..

Martin Fowlers document about what IoC is.. is too long.. I learn stuff by
looking at lots of examples. The 3 links you have on your page that should
explain its concept.. I don't understand them at all.. sorry.

Copland looks interesting to me.
 
S

Sascha Ebach

Hi Jamis,
Lots of sense. As I said in my reply to Hal, though, IoC really benefits
large applications more than small ones. However, the 0.6.0 release of
Copland has a "real world" example application of a Calculator
implemented using IoC. (I put "real world" in quotes, because although
it demonstrates the techniques of programming with IoC, it's not the way
you'd really want to do a trivial calculator program.)

Ah, I stumbled upon this, but when I got through with the docs I forgot
about it. Maybe you could put a sentence at the bottom of each example
like: "For a small example program implemented with IoC see the examples
dear of the distribution" or similiar. Will have a look at it.
Also, the documentation in CVS (which will be released with 0.7.0, very
soon) includes a couple more tutorials (bringing the total to 4). The
tutorials since the rewrite are, I think, much more applicable than
before--I don't know how recently you've looked at the Copland docs.

I read the docs multiple times. Since 0.3 I think. So also the latest.
Still--I'll see if I can't think of a nice, large, "real world" example
of IoC (specifically, using Copland) and then see if I can find a good
way to present it in the documentation. Ironically, I don't have any
large examples using Copland, although I've got a couple in mind that I
keep intending to start "as soon as I'm done with Copland." ;)

The thing with building frameworks not alongside a real application is
that you usually rewrite the whole thing alot (ring a bell? ;).
Shouldn't the framework be built around / from a real world application
just like DHH did with Basecamp and Rails? At least that is the advice I
always read about in books of well known authors ;)

You wouldn't have to actually implement a complete large application.
But I suspect you could easily get to a point where you could say: "See,
if I do this the traditional way I end up writing 10000 lines of code
for 100 services/adapters, with Copland it only takes me 2000 lines of
YAML and 1000 lines of Ruby." Now this would be an argument for me to
"buy in".
Thanks for the feedback, Sascha. I'll do some thinking, too. I'll see if
I can find a better way to present IoC.

This might sound funny, but I think you would have to sell the idea
more. Like TDD is sold by saying that

- overall development is faster, less debugging, you know when you are ready
- more confidence in the code
- higher quality of code
- ...

What is the main reason for using DI? Is it to produce the same
functionality with less lines of code? Which is always excellent. In the
example you say that "unit testing is beyond the scope of this
tutorial." This actually disappointed me cause I hoped to understand it
better if I would see some tests. Wouldn't this be just another
paragraph or two (writing 1 or 2 test classes)? Or maybe you plan to do
a complete example about the way you unit test IoC containers
(environments)? Testing is using ...

I am looking forward to seeing Copland evolve and hope that I can get
around using it soon.
 
C

Carl Youngblood

What is the main reason for using DI? Is it to produce the same
functionality with less lines of code? Which is always excellent. In the

Are you sure? I can show you Lisp and Rebol code that accomplishes
more in orders-of-magnitude fewer lines than equivalent Ruby
implementations, but that does not necessarily mean that these
languages are easier to use, adapt, and understand.

Many functional programming advocates could reasonably argue that
their favorite languages are considerably more powerful than Ruby, but
I think it comes down more to personal preference and how comfortable
a language is to use. Ruby makes more sense to me than most of the
highly functional languages out there, though I have often considered
taking the plunge into more frigid functional waters. I already
thought of myself as going out on a limb when I decided to code in a
relatively-less-popular language like ruby, and when I discovered
functional languages like OCaml my world was rocked even further. For
now I'm comfortable with Ruby though.

Carl
 
S

Sascha Ebach

Hi Carl,

Carl said:
Are you sure? I can show you Lisp and Rebol code that accomplishes
more in orders-of-magnitude fewer lines than equivalent Ruby
implementations, but that does not necessarily mean that these
languages are easier to use, adapt, and understand.

Many functional programming advocates could reasonably argue that
their favorite languages are considerably more powerful than Ruby, but
I think it comes down more to personal preference and how comfortable
a language is to use. Ruby makes more sense to me than most of the
highly functional languages out there, though I have often considered
taking the plunge into more frigid functional waters. I already
thought of myself as going out on a limb when I decided to code in a
relatively-less-popular language like ruby, and when I discovered
functional languages like OCaml my world was rocked even further. For
now I'm comfortable with Ruby though.

By less lines of code I mean that the program is perfect when you can't
take anything out of it anymore. By this I don't mean obfuscating the
code or using only 1-2 letter variable names. Of course everything has
to be readable and if you look at the YAML services Jamis uses you have
to admit that they are very readable (compared to any programming
language). I have no experience with functional programming so I can't
talk about it, but if there is something like IoC for OCaml and I can
make the same program with 3000 LoC instead of 10000 LoC I am sure going
to look into it. My main motivation for using Ruby instead of Java is
the compactness of expression. Java's redundancy produces so much LoC
that I could simple not manage it. Despite the fact that there are
excellent people in the community and there are also some excellent
packages out there. I would love to be able to do work in Java, but this
is just too much work for me. As I am usually working alone this is the
most important consideration when developing. It is not the initial
development of a program. But when i have to look into the program after
6-12 months it is a major thing if I have to look through 10000 instead
of only 3000 LoC.

The last time I looked into OCaml I didn't understand a single thing ;)
Maybe I should try again.
 
J

Jamis Buck

Simon said:
On Saturday 04 September 2004 22:57, Jamis Buck wrote:
[snip]
That works, too. :) Frankly, it isn't until you ramp up to some fairly
complex applications that IoC really starts to buy you anything. (The
text editors that have recently been announced have seemed in my mind
prime candidates for IoC.) And for really small projects, it can just
get in the way. It's also not something you use "ad-hoc"--it requires a
fair bit of thought and design "up-front" to really take advantage of.



Text editor.. hmm.. im working on an editor, so now you have woken my
interest. I have looked at copland + the documents you link to, but im
affraid I don't understand what it is..

Well, I've never written a text editor. (Sascha, feel free to nail me on
that.;) However, I've written an ebook reader, so I think I have some
*minor* idea of how such a beast might go together. I'll give my opinion
of how something like a text editor might be architected using IoC.

I think you'll find that the architecture isn't very different from what
you might already have.

Basically, look at the subsystems (and the sub-subsystems, and so
forth). You might have a VFS subsystem, a command subsystem, a rendering
subsystem, and so forth. The VFS subsystem might be further broken down
into a zip abstraction, an FTP abstraction, and an abstraction for a
conventional file system.

Once you have an idea of what all the pieces are (and how they relate to
each other--that's important!) you then arbitrarily change their name
from "subsystem" to "service", and you're halfway to Copland. The
remainder of the trip involves changing your way of thinking from "the
VFS instantiates the zip abstraction, et. al." to "the VFS has a
dependency on a list of file system abstractions". The VFS _doesn't
care_ what those abstractions are, and has no code for instantiating
them. Instead, it just expects some other entity to give it that list at
some point early in its lifecycle.

That's where the container comes in. You tell the _container_ explicitly
what those dependencies are (the term that Copland uses is
"configuration point") and then when Copland is asked to instantiate a
VFS service, it will go out and follow the dependencies and instantiate
all dependent services for you. Once they are all instantiated, it then
gives the list of file system abstractions to the new VFS object, and
returns that new VFS object to the caller, you.

The benefit here is that if you want to add another abstraction, you add
the relationship between it and the VFS to a configuration file instead
of code. This means that any third-party abstraction that fulfills the
necessary contracts can be painlessly plugged into your application
without needing to modify any code.

Notice, too, that your services are just plain-old Ruby objects, but
where they used to instantiate their dependencies themselves, now they
have setters for those dependencies, and expect to be given them at
creation time. This has benefits for unit testing, too, since you can
easily assign mock objects to any property of a service!

Is this a new idea? No. Are you already doing something like this?
Probably. It's just good design, to minimize coupling between
components. All an IoC container does is generalize that into a reusable
framework that you can take advantage of repeatedly and consistently.

Admittedly, most IoC containers give you more than just "dependency
injection" (which is more or less what I just described). Copland, for
instance, provides some AOP-like functionality via "interceptors", which
allow you to add code that is executed before and after (and around)
method invocations on designated services. But the dependency injection
(DI) pattern is the strong point of IoC containers.
Martin Fowlers document about what IoC is.. is too long.. I learn stuff by
looking at lots of examples. The 3 links you have on your page that should
explain its concept.. I don't understand them at all.. sorry.

Well, I hope the above wasn't too long. :) I agree, though--I haven't
ready completely through Fowler's article, either, though I've skimmed
most of it. I encountered it after I had a general idea of what IoC was
all about, though.

I'll work on getting some more comprehensive examples out.
Copland looks interesting to me.

That alone is a promising statement. Now if I can just get you to
_adopt_ it... ;)

- Jamis

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."
 
J

Jamis Buck

Sascha said:
Hi Jamis,



Ah, I stumbled upon this, but when I got through with the docs I forgot
about it. Maybe you could put a sentence at the bottom of each example
like: "For a small example program implemented with IoC see the examples
dear of the distribution" or similiar. Will have a look at it.

Good suggestion -- I'll do that.

The thing with building frameworks not alongside a real application is
that you usually rewrite the whole thing alot (ring a bell? ;).
Shouldn't the framework be built around / from a real world application
just like DHH did with Basecamp and Rails? At least that is the advice I
always read about in books of well known authors ;)

I knew someone would try to call me on that. ;) What is actually
happening is this: I use the HiveMind IoC container at work (for Java),
and have really found it powerful and useful. I found myself wishing
there was something like it for Ruby... and so Copland was born. There
are a few applications I want to write, but haven't had the time yet,
and I wanted to do them in Ruby using IoC. I may not have actually used
Copland for anything yet, but Copland is a not-quite-clone of HiveMind,
and I *have* been using HiveMind, extensively. :)
You wouldn't have to actually implement a complete large application.
But I suspect you could easily get to a point where you could say: "See,
if I do this the traditional way I end up writing 10000 lines of code
for 100 services/adapters, with Copland it only takes me 2000 lines of
YAML and 1000 lines of Ruby." Now this would be an argument for me to
"buy in".

A very good point. What you're looking for, then, are testimonials of
some sort, even they were coming from me directly. Hopefully, now that
I'm feeling more confident in Copland's stability and basic feature set,
I'll be starting on some of my UFO's ("unfinished objects", from
knitting terminology). Once those are working reasonably, I can probably
oblige you and others with a few testimonials and comparisons.
This might sound funny, but I think you would have to sell the idea
more. Like TDD is sold by saying that

- overall development is faster, less debugging, you know when you are
ready
- more confidence in the code
- higher quality of code
- ...

Doesn't sound funny at all, actually. I think you're absolutely right.
I've tried to do some of that in the manual, but the attempt obviously
missed. I'll see if I can compose a nice, concise, bulleted list of
benefits that IoC provides.
What is the main reason for using DI? Is it to produce the same
functionality with less lines of code? Which is always excellent. In the
example you say that "unit testing is beyond the scope of this
tutorial." This actually disappointed me cause I hoped to understand it
better if I would see some tests. Wouldn't this be just another
paragraph or two (writing 1 or 2 test classes)? Or maybe you plan to do
a complete example about the way you unit test IoC containers
(environments)? Testing is using ...

Well, unit testing was beyond the scope of _that_ tutorial. I do plan on
having a tutorial or example that shows how unit testing is made more
possible (not necessarily easier) by using an IoC framework. I'm stuck
in a tough spot, though--write documentation, or mature the framework?
Both are equally important, and I've tried to strike a balance. More
documentation is always pending. :)
I am looking forward to seeing Copland evolve and hope that I can get
around using it soon.

Me too! Thanks very (very!) much for the feedback, Sascha. I can tell
you've thought about this.

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."
 
S

Simon Strandgaard

Simon Strandgaard wrote: [snip]
Basically, look at the subsystems (and the sub-subsystems, and so
forth). You might have a VFS subsystem, a command subsystem, a rendering
subsystem, and so forth. The VFS subsystem might be further broken down
into a zip abstraction, an FTP abstraction, and an abstraction for a
conventional file system.

Once you have an idea of what all the pieces are (and how they relate to
each other--that's important!) you then arbitrarily change their name
from "subsystem" to "service", and you're halfway to Copland. The

ah.. changing subsystem to service.. it begins to making sense to me.
The FreeRIDE project uses something similar, with services that can be loaded,
started, stopped, etc. I think thier IoC is named FreeBase?

[snip long]
Notice, too, that your services are just plain-old Ruby objects, but
where they used to instantiate their dependencies themselves, now they
have setters for those dependencies, and expect to be given them at
creation time. This has benefits for unit testing, too, since you can
easily assign mock objects to any property of a service!

I use lots of mocks in my testcode..

Is this a new idea? No. Are you already doing something like this?
Probably. It's just good design, to minimize coupling between
components. All an IoC container does is generalize that into a reusable
framework that you can take advantage of repeatedly and consistently.

Im not doing so at the moment.. instead im using template method pattern.
The class in the 'main.rb' file is derived from the CommandLine class.. main
just fills in the glue code.. so that I can unittest the CommandLine class on
its own.

I now see places where IoC could be useful.. require 'fox' which loads fox
toolkit and in case it isn't present on the users machine.. then it outputs a
nice message.. This could be encapsulated as a service.

If I extended my editor with a ruby-debugger then this would be good to have
encapsulated as a service.


I want subsystems to be defined in the configuration file.. so that things
which doesn't belong in the editor doesn't bloat it. Maybe copland is the
solution to setting up services in these configuration files?

Admittedly, most IoC containers give you more than just "dependency
injection" (which is more or less what I just described). Copland, for
instance, provides some AOP-like functionality via "interceptors", which
allow you to add code that is executed before and after (and around)
method invocations on designated services. But the dependency injection
(DI) pattern is the strong point of IoC containers.

That can be useful for debugging.

FreeBASE has a logging system.. where each service can have their own log.
Do you provide similar feature?

Well, I hope the above wasn't too long. :) I agree, though--I haven't
ready completely through Fowler's article, either, though I've skimmed
most of it. I encountered it after I had a general idea of what IoC was
all about, though.

Ok.. I think I have gotten an idea about copland.

I'll work on getting some more comprehensive examples out.
Great



That alone is a promising statement. Now if I can just get you to
_adopt_ it... ;)

At the moment im busy with my studies and kind of lacks time.. I think I will
do some experiments with for my configuration system with copland. But I
cannot promise that I will use copland, nor when I will do these experiments.
 
J

Jamis Buck

Simon said:
Simon Strandgaard wrote:
[snip]

Basically, look at the subsystems (and the sub-subsystems, and so
forth). You might have a VFS subsystem, a command subsystem, a rendering
subsystem, and so forth. The VFS subsystem might be further broken down
into a zip abstraction, an FTP abstraction, and an abstraction for a
conventional file system.

Once you have an idea of what all the pieces are (and how they relate to
each other--that's important!) you then arbitrarily change their name
from "subsystem" to "service", and you're halfway to Copland. The


ah.. changing subsystem to service.. it begins to making sense to me.
The FreeRIDE project uses something similar, with services that can be loaded,
started, stopped, etc. I think thier IoC is named FreeBase?

Interesting -- I'll have to look at that. Might be a good place to glean
ideas from. :)
I want subsystems to be defined in the configuration file.. so that things
which doesn't belong in the editor doesn't bloat it. Maybe copland is the
solution to setting up services in these configuration files?

Copland could be one solution. I've maintained for a long time that
there is nothing you can do with IoC that you couldn't do without it.
It's merely one approach to the problem.

FreeBASE has a logging system.. where each service can have their own log.
Do you provide similar feature?

Yup. When using the BuilderFactory (or related factory service) to
construct a new service, you can specify that a logger be passed as a
constructor parameter, or set as a property on the new object. That's
how the logging interceptor works, using the logger for the service it
is wrapping.

(There's a chapter in the Copland manual in CVS about factory
services--when I release 0.7.0 I'll post the updated manual as well.
Hopefully that chapter will make the above paragraph a bit more
understandable.)
At the moment im busy with my studies and kind of lacks time.. I think I will
do some experiments with for my configuration system with copland. But I
cannot promise that I will use copland, nor when I will do these experiments.

No worries. But if you do start to tinker with it, you might want to
join the copland-users mailing list
(http://rubyforge.org/mailman/listinfo/copland-users). I'll be happy to
answer any questions you have.

--
Jamis Buck
(e-mail address removed)
http://www.jamisbuck.org/jamis

"I use octal until I get to 8, and then I switch to decimal."
 

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,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top