Brain Fart Moment. Aliasing a method with params.

Discussion in 'Javascript/Plugin Support' started by DarknessFalls, Oct 27, 2015.

  1. DarknessFalls

    DarknessFalls Rpg Maker Jesus - JS Dev. Veteran

    Messages:
    1,393
    Likes Received:
    209
    First Language:
    English
    Consider the following:

    var spriteCharacterInitializeMethod = Sprite_Character.prototype.initialize;Sprite_Character.prototype.initialize = function(character) {    spriteCharacterInitializeMethod.call(this, arguments);};

    This breaks the game, because of some .bind cannot be called. How do you alias (override) methods that require a parameter to be passed in?

    Doing:

    var spriteCharacterInitializeMethod = Sprite_Character.prototype.initialize;Sprite_Character.prototype.initialize = function(character) {    spriteCharacterInitializeMethod.call(this, arguments);};Doesn't break the game, but A) character is undefined, and B) other issues arise doing this ... 
     
    Last edited by a moderator: Oct 27, 2015
    #1
  2. Iavra

    Iavra Veteran Veteran

    Messages:
    1,797
    Likes Received:
    856
    First Language:
    German
    var _initialize = Sprite_Character.prototype.initialize;
    Sprite_Character.prototype.initialize = function(character) {


    _initialize.call(this, arguments);


    };

    Passing "arguments" automatically passes all parameters to the underlying function. You can also just use "character", but the generic way ensures, that no parameters get lost.
     
    Last edited by a moderator: Oct 27, 2015
    #2
  3. DarknessFalls

    DarknessFalls Rpg Maker Jesus - JS Dev. Veteran

    Messages:
    1,393
    Likes Received:
    209
    First Language:
    English
    So this doesn't work for me : I get Type Error, undefined is not a function. upon exploring the stack trace I see, the first line it explodes on is:

    Sprite_Character.prototype.updateVisibility = function() {    Sprite_Base.prototype.updateVisibility.call(this);    if (this._character.isTransparent()) {        this.visible = false;    }};Specifically:

    if (this._character.isTransparent()) { ... }Which means character is not being passed because this._character is "undefined"

    This is the only code I have in the file

    Just an update, when I pass in character, I get cannot read property 'bind' of undefined, which is thrown in pixi ... 
     
    Last edited by a moderator: Oct 27, 2015
    #3
  4. altorn

    altorn Veteran Veteran

    Messages:
    53
    Likes Received:
    12
    Location:
    Toronto, Canada
    First Language:
    English
    Just throwing this out there, could be a stupid answer, but have you tried using .apply() instead of .call()?

    As far as i know, .call() needs you to list out the parameters instead of them all in an array.

    If you really need to use call, have you tried .call(this, character, arguments)?
     
    Last edited by a moderator: Oct 27, 2015
    #4
  5. DarknessFalls

    DarknessFalls Rpg Maker Jesus - JS Dev. Veteran

    Messages:
    1,393
    Likes Received:
    209
    First Language:
    English
    Exact same issue with the whole bind error thats being thrown.

    Update

    the correct answer is to not touch the initialize function but use the initMembers function >.>
     
    Last edited by a moderator: Oct 27, 2015
    #5
  6. altorn

    altorn Veteran Veteran

    Messages:
    53
    Likes Received:
    12
    Location:
    Toronto, Canada
    First Language:
    English
    What parameters does Sprite_Character.initialize() normally accept? Just the "character" parameter?

    var spriteCharacterInitializeMethod = Sprite_Character.prototype.initialize;Sprite_Character.prototype.initialize = function(character) { spriteCharacterInitializeMethod.call(this, character);};And the above doesn't work?

    I tried this quickly in my browser's console and got correct results:

    Code:
    var ttt = function() {   this.a = 0;}ttt.prototype.test = function(a) {  console.log('a');   console.log(a);}var bbb = new ttt();console.log(bbb.test);var xxx = ttt.prototype.test;console.log(xxx);ttt.prototype.test = function( {   console.log('new');   xxx.call(this, ;}bbb.test('hello');
     
    Last edited by a moderator: Oct 27, 2015
    #6
  7. GaryCXJk

    GaryCXJk Veteran Veteran

    Messages:
    88
    Likes Received:
    46
    Location:
    Zaandam, the Netherlands
    First Language:
    Dutch
    Okay, here's what's the issue.

    The issue wasn't that you used initialize. Initialize technically isn't a JavaScript standard function of an object, so overriding that wouldn't really be a problem. The issue is what the above mentioned.

    call requires one parameter for the target and one for each extra parameter that needs to get passed.

    So, for example, you have the following function:

    var getThisFreakingDuckAwayFromMe = function(fromWho) { this.awayTarget = fromWho;}Now, to use call, you'd have to use:
    Code:
    var fhqwhgads = {};getThisFreakingDuckAwayFromMe.call(fhqwhgads, "Strong Bad");
    This will set the property awayTarget of fhqwhgads to "Strong Bad", which can be seen by using console.log(fhqwhgads.awayTarget).Note that if you call it like this:

    Code:
    var getDragon = function(target) {  var dragon = {};  getThatFreakingDuckAwayFromMe.call(fhqwhgads, arguments);  return fhqwhgads;}var sIsForSucks = getDragon("Strong Sad");
    will give the following output for sIsForSucks.awayTarget:
    Code:
    ["Strong Sad"]
    Note that it is now an array, as arguments is an array. Now, change the following line:
    Code:
      getThatFreakingDuckAwayFromMe.call(fhqwhgads, arguments);
    with the following line:
    Code:
      getThatFreakingDuckAwayFromMe.call(fhqwhgads, target);
    You'd get the correct output:
    Code:
    "Strong Sad"
    Now, apply takes an array of arguments, and processes them as such. Let's take the following:
    Code:
    var sortPeorple = function(awesome) {  this.awesome = awesome;  this.tryToFade = arguments[1];  this.notImportant = arguments.slice(2);}
    Let's now use the following code:
    Code:
    var getAwesome = function() {  var tripleAList = {};  sortPeorple.apply(tripleAList, arguments);}var youCantHandleMyStyle = getAwesome('Strong Bad', 'Coach-Z', 'Homsar', 'The Poopsmith', 'King of Town');
    Here, you can see that youCantHandleMyStyle.awesome and youCantHandleMyStyle.tryToFade outputs a string and youCantHandleMyStyle.notImportant outputs an array.
    Code:
    "Strong Bad""Coach-Z"["Homsar", "The Poopsmith", "King of Town"]
    So that's essentially what the difference is between call and apply.
     
    #7

Share This Page