Https://repl.it/@bennypr0fane/loops

Hello,
In this repl, my loopUntil() function is kinda not working.
If I call it with arguments ("m", $alphabet), I’d expect it to return an array that contains all the letters from a to m, but it’s empty (to see it, press “Run”).
Even after explaining it to my rubber ducky, I think it should do the trick.
What am I missing?
Something in the back of my head tells me I got the if-else backwards (hence the tag), but I can’t think of another way to do it.

the array to which you push your results:

$alphaUntil = array();

is defined in the loop. Each iteration of the loop, the array gets “reset” to an empty array.

1 Like

Thanks, that makes sense. Actually my first approach was to define it outside the loop:

$alphaUntil = array();
function loopUntil(string $until, array $listOfLetters) {
  for ($x=0; $x < count($listOfLetters); $x++) {   
    
    if ($until == $listOfLetters[$x]){
      return $alphaUntil;
    } else {
      array_push($alphaUntil, $listOfLetters[$x]);
    }
  }
}

$loopUntilM = loopUntil("m", $alphabet);
print_r($loopUntilM);

But here php complains that array_push() is being handed a null argument:

PHP Warning: array_push() expects parameter 1 to be array, null given in /home/runner/loops/main.php on line 29

Even though it’s only a warning, it seems that the function call or at least the print command is never executed.

You’re getting that warning because loopUntil() doesn’t have access to $alphaUntil, as it’s outside the scope of the function.

If you want access to your global variable inside the function, you should declare it as global

function loopUntil() {
  global $alphaUntil;
}
1 Like

The warning very likely exist for a good reason.

I also don’t agree with @ghostlovescore suggestion. Why would you break scope/encapsulation unnecessarily?

could we declare the variable in the scope of the function but not inside the loop to prevent the “reset” every iteration?

Thank you, this gives the desired output: :smiley:

function loopUntil(string $until, array $listOfLetters) {
  $alphaUntil = array();
  for ($x=0; $x < count($listOfLetters); $x++) {   
    if ($until == $listOfLetters[$x]){
      return $alphaUntil;
    } else {
      array_push($alphaUntil, $listOfLetters[$x]);
    }
  }
}

Thanks, I wasn’t aware that php variables have this option/need for explicitly assigning scope.
Python is the first language that I learned and iirc, it has variable scope working like this:
variables inside a block of code can’t be accessed from the outside, but statements in any block of code can access all the variables declared outside of that block.
I guess this rule set is my default assumption until I learn otherwise.

  1. Would you say that’s a bad default assumption to make about a new language (taking into account that assumptions can only ever take you so far)?
  2. If I wrote this in Python, would the array_push() function be able to work on a variable declared outside?

@ghostlovescore, I’m now playing around with your solution to make sure I understand the global keyword.
It would seem that it’s basically saying:
“when this variable occurs in this function, it refers to the one that was declared outside.”
In that sense, it would actually be a reference rather than a declaration, correct?

  1. I think its a dangerous assumption. You should learn about the scope rules of a language. Once you know 3 or 4 languages, this becomes a lot easier. You will also start distinguish what good scope rules are.

Yes, that would work. But its the wrong question. You shouldn’t do this, it create bugs.

Have you completed the python course? There is an anti vowel challenge (removing all the vowels from a string). Some people decide to append all constants to a new list. A wise decision, but sometimes they do this:

result = []
def anti_vowel(text):
   # appending the consonants

now, if we called the function multiple times, the second function call/string will also contain information from the first function call/string.

1 Like

Well it wasn’t a suggestion, I was simply stating that IF you want to access a global variable inside a function, then you’d need to declare it as global.

My mistake because you’re absolutely correct, it’s not the best practice around. It’s definitely best to avoid using global variables like this.

Should have been more thorough in answering this, my bad @bennypr0fane.

2 Likes