Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Assigning to self

  1. #1
    Join Date
    May 2007
    Location
    USA
    Posts
    373
    Thanks
    2
    Thanked 4 Times in 4 Posts

    Default Assigning to self

    Code:
    RegExp.prototype.addFlags = function(flags) {
    	if(flags.match(/[^gim]/i)) return false;
    	var newFlags = flags.split("");
    	var temp = this.toString();
    	temp = temp.substr(1, temp.length-1).replace(/\/([^\/]*)$/, "")
    	var oldFlags = RegExp.$1;
    	for(var i=0; i<newFlags.length; i++) {
    		if(oldFlags.indexOf(newFlags[i])==-1) oldFlags += newFlags[i];
    		}
    	return new RegExp(temp, oldFlags);
    	//I want something like: this = new RegExp(temp, oldFlags);  (If this worked that is...)
    	}
    Where I have the bolded code is where I'm stuck. What I want to do is have the addFlags not return the new RegExp and instead change the variable object it is acting upon.
    Code:
    var pattern = /abc/i
    pattern.addFlags("gm")
    alert(pattern) //Currently outputs "/abc/i". I want it to output "/abc/gim"
    pattern = pattern.addFlags("gm")
    alert(pattern) //Outputs "/abc/gim"
    Last edited by Trinithis; 05-24-2007 at 09:24 PM.

  2. #2
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Flags seem to be read-only on RegExp instances, so I don't think you can. Getting the properties of the current object can be done a better way though:
    Code:
    if(typeof Array.prototype.indexOf !== "function")
      Array.prototype.indexOf = function(val) {
        for(var i = 0; i < this.length; ++i)
          if(this[i] === val)
            return i;
        return -1;
      };
    
    Array.prototype.unique = function() {
      var r = [], i;
      for(i = 0; i < this.length; ++i)
        if(r.indexOf(this[i]) === -1)
          r.push(this[i]);
      return r;
    };
    
    RegExp.prototype.addFlags = function(flags) {
      var oldFlags = [], text = this.source;
      for(var x in {'global' : false, 'ignoreCase' : false, 'multiline' : false})
        if(this[x])
          oldFlags.push(x[0]);
      return (new RegExp(this.source, oldFlags.concat(flags.split("")).unique().join("")));
    }
    Last edited by Twey; 05-25-2007 at 07:01 PM. Reason: Fix stupid logic error.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  3. #3
    Join Date
    May 2007
    Location
    USA
    Posts
    373
    Thanks
    2
    Thanked 4 Times in 4 Posts

    Default

    Sorry, let me re-explain myself. I want to create a method that changes an object into a new object without using return.

    What I don't want:
    var x = new Object();
    x = x.changeX();

    What I want:
    var x = new Object();
    x.changeX();
    Last edited by Trinithis; 05-24-2007 at 09:05 PM.

  4. #4
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    To repeat myself:
    Flags seem to be read-only on RegExp instances, so I don't think you can.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  5. #5
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Most built-in objects are immutable. The only exception that comes to mind is a Date instance.
    Mike

  6. #6
    Join Date
    May 2007
    Location
    USA
    Posts
    373
    Thanks
    2
    Thanked 4 Times in 4 Posts

    Default

    Actually, I just got it to work the way I wanted it to (by accident too . I read about the compile method, thinking it was like new RegExp, but it just timed faster with my tests, so I unwittingly kept it).
    Code:
    RegExp.prototype.addFlags = function(newFlags) {
    	var flags = "";
    	if(newFlags.indexOf("g")!=-1 || this.global) flags += "g";
    	if(newFlags.indexOf("i")!=-1 || this.ignoreCase) flags += "i";
    	if(newFlags.indexOf("m")!=-1 || this.multiline) flags += "m";
    	return this.compile(this.source, flags);
    	}
    var r = /foo/;
    r.addFlags("ig");
    alert(r); // Outputs "/foo/gi" (or "/foo/ig" depending on the browser)
    alert(r.addFlags("m")); // Outputs "/foo/gim"
    Now I have to finish coding other RegExp methods.
    Last edited by Trinithis; 05-25-2007 at 07:16 PM.

  7. #7
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Very nice! I wonder if those properties:

    obj.ignoreCase
    obj.multiline

    of the RegExp object could be used as part of tests to see if the browser supports the i or m flags? I'm thinking probably. But, no real time to play with it right now.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  8. #8
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Ah! Well done, I shall bear this one in mind
    I wonder if those properties:

    obj.ignoreCase
    obj.multiline

    of the RegExp object could be used as part of tests to see if the browser supports the i or m flags?
    If the browser didn't support i or m, there'd be no reason for it to have ignoreCase or multiline. I suspect it would be reasonable to assume:
    Code:
    RegExp.supportsFlag = (function() {
      var emptyRegex = new RegExp(),
        possibleFlags = {
          'g' : 'global',
          'i' : 'ignoreCase',
          'm' : 'multiline'
        };
      return function(flag) {
        return !(typeof emptyRegex[possibleFlags[flag]] === "undefined");
      };
    })();
    Last edited by Twey; 05-25-2007 at 07:31 PM.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends français | entiendo español | tôi ít hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  9. #9
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Yeah, I think that would work. I was looking for something more straightforward and hit it on the second shot (at least for supporting browsers):

    Code:
    if (typeof RegExp().ignoreCase=='boolean')
    we can use the i flag here
    else
    do something to simulate case insensitivity here
    The trick is to see if it works as expected in non-supporting browsers.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  10. #10
    Join Date
    May 2007
    Location
    USA
    Posts
    373
    Thanks
    2
    Thanked 4 Times in 4 Posts

    Default

    You're going to have a hard time emulating flags that browsers do not support because JS does not support the regex inline mode "flags" (?g) (?i) (?m)... or at least both mine don't, and since they don't, I would suspect even older browsers would not.

    If anything, if one were to use flags in the first place (setting aside all but the basic RegExp class) and a browser did not support it, then you are out of luck to begin with, before adding new methods. My case is that if you are worried about unsupporting browsers, then do not use flags to begin with.

    BTW, are there even browsers that support regular expressions and not flags? Or if some only support 1 or 2 of them, then my code would return 'undefined' with let's say 'this.ignoreCase' and in the if-statement, it would act as 'false' and you have nothing to worry about anyway.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •