Using "new function() {...}" as a Singleton

S

Scott Sauyet

(I know I've seen a discussion of this here not too long ago, but
search is failing me. Any pointers to prior threads would be
appreciated.)

I'm pretty sure posters here had some reasonable critiques of using
this style to declare a singleton:

var singleton = new function() {
var privateProp1 = //...
var privateFn = function(...) {...}
this.publicProp1 = // calculated using privateProp1 and
privateFn1
this.publicProp2 = // calculated using privateProp1 and
privateFn1
};

Obviously I could do this instead:

var singleton = (function() {
var privateProp1 = //...
var privateFn = function(...) {...}
return {
publicProp1: // calculated using privateProp1 and privateFn1,
publicProp2: // calculated using privateProp1 and privateFn1
};
};

But the former syntax seems somewhat cleaner. Are there good reasons
not to use it?

Thanks for any feedback,
 
S

Scott Sauyet

Scott Sauyetwrote:

Sorry, bad wrapping. This is what I meant:

  var singleton = new function() {
    var privateProp1 = //...
    var privateFn = function(...) {...}
    this.publicProp1 = // calc using privateProp1 and privateFn1;
    this.publicProp2 = // calc using privateProp1 and privateFn1;
  };
 
G

Garrett Smith

Scott said:
(I know I've seen a discussion of this here not too long ago, but
search is failing me. Any pointers to prior threads would be
appreciated.)

I'm pretty sure posters here had some reasonable critiques of using
this style to declare a singleton:

var singleton = new function() {
var privateProp1 = //...
var privateFn = function(...) {...}
this.publicProp1 = // calculated using privateProp1 and
privateFn1

<snip>

You want to know which is better: 1 or 2. Based on what was written, I
interpreted those as (1) creating a NewExpression and assigning
properties to `this` vs (2) calling a function that returns an object.
Your example #2 did not show the function being called but I assumed
that is what you meant.

//Example 1:
var singleton = new function() {
var privateProp = 1;
function privateFn( ) {
return privateProp + Math.random();
}
this.publicFn = privateFn;
};

//Example 2:
var singleton = (function(){
var privateProp1 = 1;
function privateFn() {
return privateProp1 + Math.random();
}
return {
publicFn : privateFn
};
})();

Did I get that right?

I find both easy to understand.

#1 has a longer prototype chain but is shorter to write. Line 1 has a
NewExpression, which shows that an object is being created and will be
assigned to identifier `singleton`.

Based on the context, I don't have much else to say.

When posting NG code, it is a good idea to make sure that it is
executable as transmitted and to format the lines to 72 characters wide
to avoid wrapping.
 
S

Scott Sauyet

Garrett said:
Scott Sauyet wrote:
You want to know which is better: 1 or 2. Based on what was written, I
interpreted those as (1) creating a NewExpression and assigning
properties to `this` vs (2) calling a function that returns an object.

Yes, that's what I intended.
Your example #2 did not show the function being called but I assumed
that is what you meant.

//Example 1:
var singleton = new function() {
   var privateProp = 1;
   function privateFn( ) {
     return privateProp +  Math.random();
   }
   this.publicFn = privateFn;

};

//Example 2:
var singleton = (function(){
   var privateProp1 = 1;
   function privateFn() {
     return privateProp1 + Math.random();
   }
   return {
     publicFn : privateFn
   };

})();

Did I get that right?

Not quite. I should have added "())" before the final semicolon in
the second example, e.g.

var singleton = (function() {
var privateProp1 = //...
var privateFn = function(...) {...}
return {
publicProp1: // calculated using privateProp1 and privateFn1,
publicProp2: // calculated using privateProp1 and privateFn1
};
}());


I would not expect to make privateFn available publicly at all,
although it might be called by functions I do expose.

Perhaps a trivial-but-complete example would be in order. I could use
technique 1:

var idGen = new function() {
var rowPrefix = "row-", cellPrefix = "cell-", count=0;
var nextValue = function() {
return count++;
};
this.nextRow = function() {return rowPrefix + nextValue();};
this.nextCell = function() {return cellPrefix + nextValue();};
};
// idGen.nextRow() ==> "row-0"
// idGen.nextCell() ==> "cell-1"
// idGen.nextCell() ==> "cell-2"
// idGen.nextRow() ==> "row-3"


instead of my usual technique 2:

var idGen = (function() {
var rowPrefix = "row-", cellPrefix = "cell-", count=0;
var nextValue = function() {
return count++;
};
return {
nextRow: function() {return rowPrefix + nextValue();},
nextCell: function() {return cellPrefix + nextValue();},
}
}());
// idGen.nextRow() ==> "row-0"
// idGen.nextCell() ==> "cell-1"
// idGen.nextCell() ==> "cell-2"
// idGen.nextRow() ==> "row-3"


I do recognize that neither of these is necessarily the best way to
write these little functions. I'm just curious as to the benefits of
one technique over the other or if there are potential issues with
either.
I find both easy to understand.

#1 has a longer prototype chain but is shorter to write. Line 1 has a
NewExpression, which shows that an object is being created and will be
assigned to identifier `singleton`.

Based on the context, I don't have much else to say.

I've generally used technique 2. Today I was writing some code and
just started it out of the blue with technique 1. I'm not sure why.
It seems a little cleaner, a little clearer, though, and I really
wonder if there is some compelling reason not to use it.

When posting NG code, it is a good idea to make sure that it is
executable as transmitted and to format the lines to 72 characters wide
to avoid wrapping.

Yes it is. I apologize.
 
E

Eric Bednarz

Scott Sauyet said:
I'm pretty sure posters here had some reasonable critiques of using
this style to declare a singleton:

I’m pretty sure I would like to know how and more than all why one would
try to implement the singleton pattern in a class-free language.
 
G

Garrett Smith

Eric said:
I’m pretty sure I would like to know how and more than all why one would
try to implement the singleton pattern in a class-free language.

That type of pattern allows an object to have private scope. That
particular pattern is useful when the program must have at most one of
that object, available immediately.

There are cases where you want to hide methods. Some prefer to use _ but
this has the disadvantage in that it isn't really private.

var foo = {
_fooFunc : function(a){
return a + 9;
},

fooFunc : function(a) {
return this._fooFunc(+a||0) + Math.random();
}
};

Pretend private makes it harder to refactor because once the method is
exposed, there is no guarantee of where it is being called from. ANd so
it might be better to have *real* private, like this:

var foo = new function(){
// Once, in the microcosm of foo...
function fooFunc(a) {
return a + 9;
}

this.fooFunc = function(a) {
return fooFunc(+a||0) + Math.random();
}
};

The benefit is that you get real private. Granted, there are some
security holes with arguments.caller, but that is mitigated here by
unary `+` operator.

Other benefits to using a closure here are that the identifiers will be
resolved more quickly and, if minification is used, will get munged to a
single letter, making them smaller and reducing the total file size,
both before and after gzip.
 
G

Garrett Smith

Garrett said:
[...]


The benefit is that you get real private. Granted, there are some
security holes with arguments.caller, but that is mitigated here by
unary `+` operator.
make that "function.caller". There are some security holes with
function.caller.
 
S

Scott Sauyet

I’m pretty sure I would like to know how and more than all why one would
try to implement the singleton pattern in a class-free language.

Whether you call it the Singleton pattern or not, there are times when
I would like several functions that have a shared, but private state.
The easiest way I can think of doing that is encapsulating them in a
single object. Is there a better way to do that?
 
T

Thomas 'PointedEars' Lahn

Garrett said:
make that "function.caller". There are some security holes with
function.caller.

With `arguments.caller', too, as given a function with identifier `function'
(which cannot exist) if supported both would refer to the same object.

Function.prototype.caller is supported since JavaScript 1.0 and JScript 2.0.

arguments.caller is supported since JavaScript 1.1, but has been deprecated
since JavaScript 1.3, and was eventually removed in JavaScript 1.5. It was
never supported by JScript as such (in JScript 5.6 it refers to an object
that cannot be called even if the caller is a Function instance).

arguments.caller was never implemented by other known implementations and it
is likely that this applies to Function.prototype.caller, too. So far
neither feature can be considered safe-to-use (regardless of security
issues).

<https://developer.mozilla.org/En/Co...Functions_and_function_scope/arguments/caller>
<http://msdn.microsoft.com/en-us/library/7t96kt3h(VS.85).aspx>
<http://PointedEars.de/es-matrix#f> (to be updated accordingly)


PointedEars
 
J

John G Harris

That particular pattern is useful when the program must have at most
one of that object, available immediately.
<snip>

If there are no classes, how can there be more than one of anything :)

This illustrates one reason why I say that 'class' is too useful a word
to be restricted to one possibly future keyword.

John
 
A

Andrea Giammarchi

new expression is basically an "elegant" module pattern recognizable
since the beginning.

var o = (function () {}());

what can "o" be? just everything, included undefined.

var o = new function () {};

what can "o" be in above case? Inevitably an object ;-)

About the "longest prototype", being the pattern self declarative, in
the meaning that the inline constructor (expression) does not suppose
to have any prototype property/method, I can't see concrete side
effects since the instance will always call it's properties/methods
and rarely those inherited via the Object.prototype.

If this is an issue, we can always attach some method, if we need it

var o = new function () {

// up to callee.prototype.__proto__
var hasOwnProperty = this.hasOwnProperty;
// then
hasOwnProperty.call(this, key);
// hasOwnProperty is "secure" here


// or prolix ...
this.hasOwnProperty = Object.prototype.hasOwnProperty;

// or ... redefine the inherited
this.hasOwnProperty = this.hasOwnProperty;

};

Side effects for 2nd and 3rd way, hasOwnProperty will become
enumerable (JScript a part) but I think this is not an issue if
performances are compromised because of the double chain (over an
empty prototype ... again, I don't think these are real bottlenecks in
today applications)

About minifiers, mungers, obfuscators, etc, the module pattern wins
for the simple reason that "this" cannot be optimized. The simplest
solution for this problem is the current one:

var o = new function () {

var self = this;

// no this anymore
self.getStuff = function () {
return self.stuff;
};
};

self, that, $this, all valid alias able to boost up minification ratio
plus in latter example there will always be a "self" reference in that
scope which means that every method will become automatically bound to
the singleton. Sometimes this is a "nice have" but surely weare free
to use "this" inside the method.

I don't think above snippet comes easily and naturally with the module
pattern ... e.g.

var o = (function () {
// private thingy
var self = {
method: function () { self ... }
};

return self;
}());

To me above example is a bit harder to read and it looks like a missed
"new expression" rather than a module pattern ... but this is more a
matter of style/habit I guess.

The only advantage in fact of readability is what the closure can
accept from the "outer world"

var o = (function (slice, snap) {
var privateWorld = "something here";
return { ... };
}(Array.prototype.slice, someInlineSnapshot()));

This is not possible with the new expression pattern, but surely we
can always do the same directly inside the expression scope, using
arguments as "reminder"

var o = new function (slice, snap) {

// private for JSLint sake
var self = this;

// outer world assignments
slice = Array.prototype.slice;
snap = someInlineSnapshot();

// rest of the code here

};

Using all these practices could result into clearer and cleaner code,
don't you agree?

About *singleton*, a pattern simply describes a solution for a generic/
common/abstract problem and the *singleton* meaning in this case is:
create an instance being "sure" its class/constructor won't create/
initialize any other

Accordingly, in ES3 we are kinda forced to shadow the constructor via
re-assignment:

var o = new function () {

var self = this;

self.constructor = Object;

};

Unfortunately, (delete o.constructor) will make the assignment
pointless, this is why we all love ES5 and Object.defineProperty:

var o = new function () {

var self = this;

Object.defineProperty(self, "constructor", {
value: Object,
writable: false,
configurable: false,
enumerable: false
});

};

But since latest example won't work right now as expected, our last
resource is to hack the prototype inline.

var o = new function () {

var self = this;

// goodbye constructor
self.constructor.prototype.constructor = Object;

};

Finally, back to the initial double chain problem, last trick shows
how to make things "faster"

var o = new function () {

var self = this;

// avoid extra lookup

// BEFORE: no more double chain
self.constructor.prototype.hasOwnProperty =
Object.prototype.hasOwnProperty;

// LAST THING TO DO: goodbye constructor
self.constructor.prototype.constructor = Object;

};

We could alias the proto easily but unfortunately "hasOwnProperty"
will be still exposed in a forIn loop so latest example does not
really bring anything new into this scenario.

I think this is pretty much it about differences, have I missed
anything?

Best Regards,
Andrea Giammarchi
 
D

David Mark

Andrea said:
new expression is basically an "elegant" module pattern recognizable
since the beginning.

var o = (function () {}());

Good, except the last parenthesis is in the wrong spot.
what can "o" be? just everything, included undefined.

So what?
var o = new function () {};

what can "o" be in above case? Inevitably an object ;-)

Too bad it is the wrong answer. :) Don't use that.
 
D

dhtml

new expression is basically an "elegant" module pattern recognizable
since the beginning.

var o = (function () {}());

what can "o" be? just everything, included undefined.

var o = new function () {};

what can "o" be in above case? Inevitably an object ;-)

As explained.

About the "longest prototype", being the pattern self declarative, in
the meaning that the inline constructor (expression) does not suppose
to have any prototype property/method, I can't see concrete side
effects since the instance will always call it's properties/methods
and rarely those inherited via the Object.prototype.

If this is an issue, we can always attach some method, if we need it
[...]

That looks like a bad idea.
About minifiers, mungers, obfuscators, etc, the module pattern wins
for the simple reason that "this" cannot be optimized. The simplest
solution for this problem is the current one:

Your example does not support that statement.
[...]
The only advantage in fact of readability is what the closure can
accept from the "outer world"

Ah no, that is not an advantage. Both CallExpression and NewExpression
can have Arguments (that means you can have parameters in either one).
var o = (function (slice, snap) {
    var privateWorld = "something here";
    return { ... };

}(Array.prototype.slice, someInlineSnapshot()));

This is not possible with the new expression pattern, but surely we
can always do the same directly inside the expression scope, using
arguments as "reminder"

With a NewExpression, Arguments are optional. If Arguments are
omitted, then parameters cannot be passed. To pass parameters, use
Arguments.

For example, a function may be declared and used as a constructor.

var Toy = function(n, m) {
this.n = n;
this.m = m;
};

To construct a Toy instance, you could use:

var t = new Toy;

but the result will be an object with `n` and `m` properties that have
value undefined. To pass arguments to a new expression, use the
parenthesis. For example:

t = new Toy(1, 2);

NewExpression takes a MemberExpression, and so it can be a
FunctionExpression. I suspect this may be the source of your
confusion. Here is another example of a NewExpression without
Arguments, but this time using a FunctionExpression as the
MemeberExpression.

var tt = new function(n, m) {
this.n = n;
this.m = m;
};

Again, the result is `m` and `n` are both undefined.

To fix that, we can pass arguments, just like we did before.

var tt = new function(n, m) {
this.n = n;
this.m = m;
}(1, 2);

That results in an object with `n=1` and `m = 2`

About *singleton*, a pattern simply describes a solution for a generic/
common/abstract problem and the *singleton* meaning in this case is:
create an instance being "sure" its class/constructor won't create/
initialize any other

Accordingly, in ES3 we are kinda forced to shadow the constructor via
re-assignment:

var o = new function () {

    var self = this;

    self.constructor = Object;

};

Unfortunately, (delete o.constructor) will make the assignment
pointless, this is why we all love ES5 and Object.defineProperty:

var o = new function () {

    var self = this;

    Object.defineProperty(self, "constructor", {
        value: Object,
        writable: false,
        configurable: false,
        enumerable: false
    });

};

I don't see the point in that.
But since latest example won't work right now as expected, our last
resource is to hack the prototype inline.

var o = new function () {

    var self = this;

    // goodbye constructor
    self.constructor.prototype.constructor = Object;

};

Finally, back to the initial double chain problem, last trick shows
how to make things "faster"

var o = new function () {

    var self = this;

    // avoid extra lookup

    // BEFORE: no more double chain
    self.constructor.prototype.hasOwnProperty =
Object.prototype.hasOwnProperty;

    // LAST THING TO DO: goodbye constructor
    self.constructor.prototype.constructor = Object;

};

The assignment to `self` is pointless. Instead, the `this` keyword can
be used.

Creating an enumerable property "hasOwnProperty" does not seem
worthwhile.

Posting via GG because I made the uninformed choice to upgrade to
Thunderbird 3.
 
D

dhtml

Good, except the last parenthesis is in the wrong spot.




So what?

The point he is trying to make, AIUI, is that the seeing a grouped
function does not imply that an object will be returned.

With NewExpression, an object results. Since functions can return a
value, and a newExpression callsa function, it might seem like the
function could return a primitive, however that is not going to result
in the returned value being a primitive. The obvious case is where a
function returns undefined, as most constructors do:

function T(){} // Constructor returns undefined.
var t = new T();

You can see that the function returned undefined and the result was a
new object.

function A(){ return 12; }
var a = new A;
typeof a; // "object"

Only when the function returns an object, does newExrpression return
that value:

function A(){ return A }
var a = new A;
typeof a; // "function"

The result of the constructor was a function (actually the constructor
itself is returned).

When reading the code, a NewExpression shows that an object is being
created.
Too bad it is the wrong answer.  :)  Don't use that.

The only way it cannot be an object is if the function throws an
error.
 
D

David Mark

dhtml said:
The point he is trying to make, AIUI, is that the seeing a grouped
function does not imply that an object will be returned.

Of course it doesn't.
With NewExpression, an object results. Since functions can return a
value, and a newExpression callsa function, it might seem like the
function could return a primitive, however that is not going to result
in the returned value being a primitive. The obvious case is where a
function returns undefined, as most constructors do:

function T(){} // Constructor returns undefined.
var t = new T();

You can see that the function returned undefined and the result was a
new object.

function A(){ return 12; }
var a = new A;
typeof a; // "object"

Only when the function returns an object, does newExrpression return
that value:

function A(){ return A }
var a = new A;
typeof a; // "function"

The result of the constructor was a function (actually the constructor
itself is returned).

When reading the code, a NewExpression shows that an object is being
created.


The only way it cannot be an object is if the function throws an
error.

That's not what I meant. I meant don't use that pattern. It's an awful
choice for a one-off. ISTM this was just discussed recently.
 
D

David Mark

Stefan said:
Isn't that more a matter of preference?
The outcome is the same in both cases.


This is really hard to search for in Google Groups (even if the search
were working correctly). I don't remember this discussion. Could you
recap why this pattern is bad?

I can't as I don't remember all of the views expressed. Personally, I
see it as very poor taste. For one, as stated, it calls a constructor
without the call operator. And it's not immediately apparent that the
developer didn't make a mistake. Perhaps they meant:-

var abc = function() {

};

....but got confused about the Function constructor. Certainly such an
error should have been apparent on execution, but perhaps they also
forgot to do anything with the result. I've seen it all. The larger
the project, the more bizarre loose ends.
 
D

dhtml

I can't as I don't remember all of the views expressed.  Personally, I
see it as very poor taste.  For one, as stated, it calls a constructor
without the call operator.  And it's not immediately apparent that the
developer didn't make a mistake.  Perhaps they meant:-

var abc = function() {

};

...but got confused about the Function constructor.  Certainly such an
error should have been apparent on execution, but perhaps they also
forgot to do anything with the result.  I've seen it all.  The larger
the project, the more bizarre loose ends.

The Function constructor has nothing to do with this pattern at all.
Misunderstanding the pattern is the mistake. The pattern itself is not

The two approaches were provided without a problem context. Although
they are similar to one another, strong conclusions of which is the
better are hard to make without a context.

Invoking an anonymous constructor is useful when your program wants an
object whose methods have access to hidden methods (to hide
implementation details). For example, an Animation Manager Registry.
The Animation Manager Registry has a simple interface:

register(animation)
unregister(animation)

The Animation Manager keeps track of how many animation objects it is
managing in a list of animations.

To preserve system resources, Animation Manager uses one setInterval
and has its own callback function to run each Animation in the
animationList. Using one setIntervale avoids performance degradation
that would otherwise occur with multiple, concurrent (setTimeout or
setInterval)s.

When an Animation's time has expired, it is notified and subsequently
removed.

When a running Animation throws an error, the error is caught and the
offending Animation is aborted immediately. Doing this prevents the
error from being thrown repeatedly, as would happen otherwise. When
the animationList becomes empty, the Animation Manager can clear the
timer using clearInterval. When the Animation Manager's `register`
method is called a timer is created, if that has not happened already.

Is the pattern applicable here?

The number of Animation Manager instances must be exactly one. The
Animation Manager provides functionality that should not be exposed.

Only the Animation Manager should be interested in whether or not it
is in a running state or how that state is maintained, what the length
of its animationList, etc. All of that is Animation Manager's private
business.

Certainly here, the pattern is not an awful choice.
 
G

Gregor Kofler

Am 2010-05-20 23:50, Andrea Giammarchi meinte:
new expression is basically an "elegant" module pattern recognizable
since the beginning.

var o = (function () {}());

what can "o" be? just everything, included undefined.

Why "everything, including undefinded"? It's just gonna be undefined.

Gregor
 
D

David Mark

dhtml said:
The Function constructor has nothing to do with this pattern at all.

No kidding. :) But at a glance, a neophyte could get confused. You
have to consider the _next_ guy.
Misunderstanding the pattern is the mistake. The pattern itself is not

It's ugly. I say don't use it.
The two approaches were provided without a problem context. Although
they are similar to one another, strong conclusions of which is the
better are hard to make without a context.

Not for me. ;)
Invoking an anonymous constructor is useful when your program wants an
object whose methods have access to hidden methods (to hide
implementation details).

But that can be done in other ways (as we've discussed).
For example, an Animation Manager Registry.
The Animation Manager Registry has a simple interface:

register(animation)
unregister(animation)

Why would I need to register an animation? Right there you lost me.
The Animation Manager keeps track of how many animation objects it is
managing in a list of animations.

Huh? With My Library, you just point and shoot.
To preserve system resources, Animation Manager uses one setInterval
and has its own callback function to run each Animation in the
animationList.

Using one setInterval is different. Not necessarily a bad idea though.
Using one setIntervale avoids performance degradation
that would otherwise occur with multiple, concurrent (setTimeout or
setInterval)s.

Yes. But at what cost in terms of the underlying code's complexity?
When an Animation's time has expired, it is notified and subsequently
removed.

Is that the (un)registration you spoke of? That casts a cloud over the
whole thing IMO.

API.showElement(el, true, {
effects: [API.effects.spin, API.effects.fade[,
ease: API.ease.cosine,
duration: 1000
});

Similar options are available for setElementHtml, setElementNodes,
changeImage, setScrollPosition, positionElement, sizeElement,
updateElement, etc.

But wait, there's more! Don't care to call tired old functions? Check
out these OO examples*:

E('myid').show(true, {
effects: API.effects.flip,
ease: API.ease.sine,
duration: 500
});

E('myid').flipIn({
ease: API.ease.sine,
duration: 500
})

E('myid').flipOut({
ease: API.ease.sine,
duration: 500
})

Q('myclass').flipIn({
ease: API.ease.sine,
duration: 500
}).removeClass('myclass').addClass('yourclass').addHtml('<p>Damn.</p>');

*Flip animation requires optional Transform add-on.

This OO layer is also optional. The underlying API has no knowledge of
it at all.

So what could be more intuitive than that? And the examples write the
code for you.

http://www.cinsoft.net/mylib-examples.html

But I digress. :)
When a running Animation throws an error, the error is caught and the
offending Animation is aborted immediately.

I don't care for that. Animations should not throw exceptions. And if
they do, the developer needs to know about them sooner rather than later.
Doing this prevents the
error from being thrown repeatedly, as would happen otherwise.

And how does that help anything?
When
the animationList becomes empty, the Animation Manager can clear the
timer using clearInterval. When the Animation Manager's `register`
method is called a timer is created, if that has not happened already.

I really think you are barking up the wrong tree with that "register"
stuff. Still, I suppose it is better than requiring a constructed
throwaway object (like in Craptaculous).
Is the pattern applicable here?

The number of Animation Manager instances must be exactly one.

There are no classes in JS. There's exactly one of everything.
The
Animation Manager provides functionality that should not be exposed.

So use the pattern I recommended (as opposed to the one I panned). I
really do know a bit about this stuff, you know?
Only the Animation Manager should be interested in whether or not it
is in a running state or how that state is maintained, what the length
of its animationList, etc. All of that is Animation Manager's private
business.

And none of that has anything to do with the topic at hand (which is
choosing the right pattern). As mentioned (by the OP!) there is a
perfectly suitable alternative.
Certainly here, the pattern is not an awful choice.

Yes, it is. You've missed the boat again. And I'm not turning it
around. Let's just agree to "disagree" here. Fair enough? :)
 
D

David Mark

Gregor said:
Am 2010-05-20 23:50, Andrea Giammarchi meinte:

Why "everything, including undefinded"? It's just gonna be undefined.

I don't know. I stopped reading after that. ;)
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top