-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No string interpolation #9
Comments
Since the question of string interpolation has been asked before, with the same argument of being more pythonic, I decided to write a counter-argument blog post (http://blog.pyjeon.com/?p=520) instead of getting into a debate in the issue tracker. I do encourage you to post a counter-argument as well, if you feel that I'm wrong. To me, implementing % for interpolation seems unpythonic, the second syntax I'm fine with, and it wouldn't be hard to implement as a library (without touching the compiler at all), since sprintf() is good enough for me, and since this is an open-source project, I'll let developers wishing this functionality to add it. |
I agree: |
Oh, it definitely includes libraries, take a look at the src/ directory. Problem is if I was to implement every library that Python has myself, I simply wouldn't have the time for any of my other work. So I implemented the few basic ones, hoping that will provide enough inspiration and guidance to others wishing to implement their own based on need. The format method you describe could easily be implemented as an optional method on a String object (that gets appended when user imports the library). This format method could then use regex to replace all occurences of "{}" with "foo" My stance with RapydScript is that the libraries are a bonus, and can be interchangeable with native JavaScript alternatives. This is why I'm quick to make changes/bug fixes to the core compiler, but prefer that community take the libraries in the direction they think works best. |
FWIW, the full spec for the |
function __stringformat__() {
// string-format from node.js
var format, lookup, resolve,
__slice = [].slice;
String.prototype._format = function _format(){
function lengthen(fname, length){
if (length == undefined) return fname
if (fname == undefined) return ''
var l, arr;
l = fname.length;
if (l > length) {
fname = fname.slice(0, l);
} else {
arr = new Array(length - l);
fname = fname + arr.join(" ");
} return fname;}
var matches, l, i, lbound, rbound, pair, compensate = 0, result = this, maybekarg = arguments.length == 1, key
matches = re('\\{[a-zA-Z_]*:([0-9]+)?\}').findall( this, true)
l = matches.length
for (i=0; i < l ; i++){
m = matches[i]
if (m[1] != undefined){
pair = m[0].split(':')
if ( pair[0] == '{' ){
// positional args
arguments[i] = lengthen(arguments[i], parseInt(m[1]) )
lbound = compensate + m.index + pair[0].length
rbound = lbound + pair[1].length
compensate += rbound - lbound
result = this.slice(0, lbound) + this.slice(rbound)
}else{
if (maybekarg && pair[0] != undefined){
key = pair[0].slice(1)
arguments[0][key] = lengthen(arguments[0][key], parseInt(m[1]) )
lbound = compensate + m.index + pair[0].length
rbound = lbound + pair[1].length
compensate += rbound - lbound
result = this.slice(0, lbound) + this.slice(rbound)
}
}
}
}
return [result, arguments]
}
format = String.prototype.format = function () {
//console('format arguments:', arguments)
var args, explicit, idx, implicit, message, _this = this;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (args.length === 0) {
return function () {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return _this.format.apply(_this, args);
};
}else{
var raw = this._format.apply(this, arguments)
args = raw[1]
_this = raw[0]
}
idx = 0;
explicit = implicit = false;
message = 'cannot switch from {} to {} numbering'.format();
return _this.replace(/([{}])\1|[{](.*?)(?:!(.+?))?[}]/g, function (match, literal, key, transformer) {
var fn, value, _ref, _ref1, _ref2;
if (literal) {
return literal;
}
if (key.length) {
explicit = true;
if (implicit) {
throw new Error(message('implicit', 'explicit'));
}
value = (_ref = lookup(args, key)) != null ? _ref : '';
} else {
implicit = true;
if (explicit) {
throw new Error(message('explicit', 'implicit'));
}
value = (_ref1 = args[idx++]) != null ? _ref1 : '';
}
value = value.toString();
if (fn = format.transformers[transformer]) {
return (_ref2 = fn.call(value)) != null ? _ref2 : '';
} else {
return value;
}
});
};
lookup = function (object, key) {
var match;
if (!/^(\d+)([.]|$)/.test(key)) {
key = '0.' + key;
}
while (match = /(.+?)[.](.+)/.exec(key)) {
object = resolve(object, match[1]);
key = match[2];
}
return resolve(object, key);
};
resolve = function (object, key) {
var value;
value = object[key];
if (typeof value === 'function') {
return value.call(object);
} else {
return value;
}
};
format.transformers = {};
}
__stringformat__(); not full implementation '{knameA:10}, {knameB:15}'.format({knameA:name, knameB:name})
'{] {} {:20}'.format(1,2,3) |
Thanks, if you want to put that into stdlib string.format() method, feel free to submit a pull request. I'd like to handle this like Python's string.format() does. I'm confused by the :10 and :15, what do they do? |
@atsepkov There is a full implementation of format() in my fork, feel free to pick it up. But note that if you pick it up you should also pick up the changes to string literal parsing. |
No string interpolation at all (neither
"%s" % "foo"
, nor"{}".format("foo")
severely limits usefulness. And no, a different synax (`vsprintf``) doesn't cut it. Just too unpythonic ..The text was updated successfully, but these errors were encountered: