sprintf.js
sprintf.js copied to clipboard
Feature Request: Object.prototype.toString.apply Type
For those who are working with things like [Symbol.toStringTag] or those who have previously and often used things like Object.prototype.toString.apply()
an ability to get that value easily would also be nice
// Map %C, open to other values, to the "Class" of an object
const classOf = o => Object.prototype.toString.call(o).replace(/\[object (.*?)\]/, '$1')
classOf(/asdfads/) // 'RegExp'
classOf(34) // 'Number'
classOf("asdfasd") // 'String'
classOf(Object.prototype) // 'Object'
classOf(null) // 'Null'
classOf(undefined) // 'Undefined'
let o = {}
o[Symbol.toStringTag] = "My Very Special Object"
classOf(o) // 'My Very Special Object'
Use of the above for a %C sprintf would be like the following
sprintf('%C', /asdfasd/); // 'RegExp'
sprintf('This object is a %C', "asdfas"); // 'This object is a String'
// etc...
Pull request and unit tests submitted. https://github.com/alexei/sprintf.js/pull/156
Is %T
not working for you?
Granted, %T
doesn't preserve the case (perhaps erroneously)
typeof
and Object.prototype.toString.call
are two very different
things. They will also return different values for the same objects.
I know, see https://github.com/alexei/sprintf.js/blob/master/src/sprintf.js#L103
NB: I edited your comment to strip my original message and your signature (which contains your email address and phone numbers)
Thanks for that. Missed %T by the way. Nonetheless, you do not want to change the case because it prevents type.name comparisons.
The way I see it there are three choices.
- Altogether reject the PR
- Break backwards compatibility for those who’ve been using %T
- Add in mine as a going forward solution and potentially deprecate the other.
Ultimately it is your repo. :)
Advantages are being able to do things like
let type = sprintf(‘%C’, function () {}) Function.name === type
Also note that my PR allows the conversion of functions to their type, also used for classes, rather than evaluating them. Potentially another use case for both.
I was indeed thinking this morning to leave the type as is and break backwards compatibility
If you do, please allow functions and classes to be converted to type rather than being executed. There are real uses for that scenario. Especially when in conjunction with classes and Symbol.toStringTag.
You may wish to use my unit test or a variation thereof as well. Feel free. Forgot to add in the assert for a Function but you can do so if you keep it since it appears you might be modifying some stuff nonetheless.
If you do, please allow functions and classes to be converted to type rather than being executed
I suppose you're talking about https://github.com/alexei/sprintf.js/pull/156/files#diff-13ed28d46a5f76f4d44561850bda81bbR61
Yup. Again I defer to your choice. With the ability to use Symbols in code to specify custom return values for Object.prototype.toString.(call|apply), I have seen usage for this pattern increase in recent years.
Regarding https://github.com/alexei/sprintf.js/issues/155#issuecomment-334185653 above:
Executing randomly submitted function values is a . . . hindrance to usage. If users cannot guarantee every value presented to sprintf-js is not tainted by being function reference, random exceptions happen.
I've been having to swap back to console.log repeatedly.
Oh dear, 7 years ago? (https://github.com/alexei/sprintf.js/commit/d84118bb4b4403eda124797e9613013aad26fdd8) We're stuck? Or can it be acknowledged as a mis-feature? Was there an obvious use case I'm ignorant of?
.
(edit) Your last comment in #157 mentions the topic.