ES3.1 Draft: String generics

Erik Arvidsson erik.arvidsson at gmail.com
Wed May 7 09:17:05 PDT 2008


The quote method needs more specification.  It needs to escape a lot
more characters than just single and double quotes.  The basic rule is
that String.prototype.quote should return a string that would be a
valid string literal for that string.

For example:

"a\nb".quote() => "\"a\\nb\""

One other way to express this is:

s == eval(s.quote())

for all strings.


Below is one implementation with unit tests

/**
 * Character mappings used internally for goog.string.quote
 * @private
 * @type {Object}
 */
goog.string.jsEscapeCache_ = {
  '\b': '\\b',
  '\f': '\\f',
  '\n': '\\n',
  '\r': '\\r',
  '\t': '\\t',
  '\x0B': '\\x0B', // '\v' is not supported in JScript
  '"': '\\"',
  '\'': '\\\'',
  '\\': '\\\\'
};


/**
 * Encloses the string in double quotes and escapes characters so that the
 * string is a valid JS string.
 * @param {string} s The string to quote.
 * @return {string} The quoted string.
 */
goog.string.quote = function(s) {
  if (s.quote) {
    return s.quote();
  } else {
    var sb = ['"'];
    for (var i = 0; i < s.length; i++) {
      sb[i + 1] = goog.string.escapeChar(s.charAt(i));
    }
    sb.push('"');
    return sb.join('');
  }
};


/**
 * Takes a character and returns the escaped string for that character. For
 * example escapeChar(String.fromCharCode(15)) -> "\\x0E"
 * @param {string} c The character to escape.
 * @return {string} The escaped string for the given character.
 */
goog.string.escapeChar = function(c) {
  if (c in goog.string.jsEscapeCache_) {
    return goog.string.jsEscapeCache_[c];
  }
  var rv = c;
  var cc = c.charCodeAt(0);
  if (cc > 31 && cc < 127) {
    rv = c;
  } else {
    // tab is 9 but handled above
    if (cc < 256) {
      rv = '\\x';
      if (cc < 16 || cc > 256) {
        rv += '0';
      }
    } else {
      rv = '\\u';
      if (cc < 4096) { // \u1000
        rv += '0';
      }
    }
    rv += cc.toString(16).toUpperCase();
  }

  return goog.string.jsEscapeCache_[c] = rv;
};

Below is a unit test for this (using JSUnit)

function testQuote() {
  var str = allChars();
  var a;
  try {
    a = eval(goog.string.quote(str));
  } catch (e) {
    fail('Quote failed: err ' + e.message);
  }
  assertEquals(str, a);

  // empty string
  str = '';
  try {
    a = eval(goog.string.quote(str));
  } catch (e) {
    fail('Quote failed: err ' + e.message);
  }
  assertEquals(str, a);

  // unicode
  str = allChars(0, 10000);
  try {
    a = eval(goog.string.quote(str));
  } catch (e) {
    fail('Quote failed: err ' + e.message);
  }
  assertEquals(str, a);
}

function allChars(opt_start, opt_end) {
  opt_start = opt_start || 0;
  opt_end = opt_end || 256;
  var rv = '';
  for (var i = opt_start; i < opt_end; i++) {
    rv += String.fromCharCode(i);
  }
  return rv;
}


2008/5/7 Pratap Lakshman (VJ#SDK) <pratapl at microsoft.com>:
>
>
>
>
> I have uploaded to the wiki a draft proposal to add a couple of generics to
> the String object. In order to retain the subset relationship with proposed
> ES4, these should be considered for addition to ES4 too.
>
>
>
> I have extracted the String portion of the ES3 spec, added a rationale (with
> hyperlinks) at the beginning, and made relevant changes to the included
> section 15.5 text, with some comments added. I have tried to be mindful of
> compat.
>
>
>
> pratap
>
>
>
>
>
>
>
> From: Brendan Eich [mailto:brendan at mozilla.com]
>  Sent: Thursday, May 01, 2008 5:21 AM
>  To: Pratap Lakshman (VJ#SDK)
>  Cc: es3.x-discuss at mozilla.org
>  Subject: Re: Static generics on String
>
>
>
>
>
> On Apr 30, 2008, at 8:58 AM, Pratap Lakshman (VJ#SDK) wrote:
>
>
>
> Yes, I did notice that these are already on String.prototype, and that they
> are generic. Is proposed-ES4 going to add a static method of the same name
> for each such prototype generic method?!
>
>
>
>
> Yes.
>
>
>
>
>
>
>
> The ES3 String.prototype methods generally specify that ToString is applied
> to "this" and to string arguments. Is it also the case for the String
> generics? If so, it would seen to limit their utility for string like
> wrappers or alternative string representations?
>
>
>
>
> The ToString is ok if you are willing to tolerate the overhead of a copy.
> Alternative is to do length and indexed accesses to the wrapper, which
> forwards to the java.lang.String or similar. But that changes how ES1-3 are
> spec'ed and it's work -- and premature optimization is the root of all evil.
>
>
>
>
>
>
>
> Is your experience that the static generic string methods have "carried
> their weight" in your implementations. In other words, based upon your
> experience would you recommend their inclusion in ES3.1?
>
>
>
>
> Not for 3.1. They are cheap to implement but 3.1 has enough to do, and the
> String static generics are not big-bang-for-the-buck.
>
>
>
>
>
>
>
> Is there a general rule for where we (proposed-ES4 & ES3.1) should add any
> new generic methods? In ES3.1 we are considering adding a "trim" and a
> "quote" method for Strings, and I was thinking of adding these on
> String.prototype (just like the other generic methods). However, the static
> generics proposal page suggests that they should then also be added as
> statics on String.
>
>
>
>
> If you skip adding any static generics for 3.1, no worries.
>
>
>
>
>
> Can you say more about quote? We've implemented it for years. Need to get it
> into both 3.1 and 4 to keep the subset relation.
>
>
>
>
>
>
>
> To conform to the rest of the ES3, I shall propose adding these methods
> (trim and quote) to String.prototype only, and not create a parallel set of
> statics.
>
> Do you see any issues with this proposal?
>
> No, that sounds good. Let's just get quote on the ES4 radar. Is there a spec
> for it?
>
>
>
>
>
> /be
> _______________________________________________
>  Es3.x-discuss mailing list
>  Es3.x-discuss at mozilla.org
>  https://mail.mozilla.org/listinfo/es3.x-discuss
>



-- 
erik



More information about the Es4-discuss mailing list