RMRK is retiring.
Registration is disabled. The site will remain online, but eventually become a read-only archive. More information.

RMRK.net has nothing to do with Blockchains, Cryptocurrency or NFTs. We have been around since the early 2000s, but there is a new group using the RMRK name that deals with those things. We have nothing to do with them.
NFTs are a scam, and if somebody is trying to persuade you to buy or invest in crypto/blockchain/NFT content, please turn them down and save your money. See this video for more information.
I'm doing this tutorial and I'm not sure if it's right.

0 Members and 1 Guest are viewing this topic.

**
Rep:
Level 46
Overlord in Training
So I'm doing this tutorial here:

http://www.rpgrevolution.com/tutorial/rgss-for-dummies-tutorial-3:-control-flow_27.html

It says:
Another thing you can do is to evaluate multiple statements at once. You can use "and", "or" and "not". You place an "and" between two statements and the new statement (statement1 and statement2) will evaluate to true if both statements are true, and to false if one or both of the statements are false. Examples:

Code:
p 1 == 1 and "hello" == "hello" # true
p 1 > 5 and 5 >= 1 # false
p 9 < 3 and 6 == 3 # false


but if I change it to this:

p 9 > 3 and 6 == 3 # I keep getting true, but one of them is false. This is an essential feature right? evaluating many at once to see if they are all true?
p 9 < 3 and 6 == 3 # false is correct.

I did some testing, and rgss just seems to ignore everything in the second half.

Am I stupid, or is this tutorial outdated?

*
Rep:
Level 82
This is actually something that stumps many people who come to using Ruby. Whilst you can use 'and' in the way you are, it doesn't actually work in the way you might be thinking it does. In fact, you might notice that these two keywords are explained under 'Control Flow' and not 'Evaluating expressions'. That's a big clue as to what the problem is and the person who wrote that guide has missed it (as many do).

Try this instead and make a note of what happens:

Code: [Select]
p 9 > 3 && 6 == 3  #true

Using 'and' and '&&' give two different results.

Also:

Code: [Select]
p (9 > 3 and 6 == 3)  #false

The difference here is the added parenthesis and it seems to be working again. This might look like it's working as you think, but that's still not really the case.

Now try this:

Code: [Select]
p 1 > 10 or 5 == 5 #false

Here we are using 'or' instead. Our expected result, however, would be true because 5 == 5. This demonstrates a limiting factor of using the 'and' and 'or' keywords instead of using the operators && and || when it comes to evaluating the truthness of some statements.

Let's look at what is happening.

For example you could have the code:

Code: [Select]
def load_save_file
  if save_file_found
   #load save file data
    return true
  else
    return false
  end
end

load_save_file or raise "unable to load save file"

If upon calling and executing load_save_file, a save file is found and loaded, and true is returned, you will not get a raised exception. However, if the method is called and it does not load a save file, it will return false. In this case, the 'or' part will be run and we will get a raised exception which tells us it was not successful (you wouldn't use it like that, but for the example we will).

With your examples, it is working fine. However, the p is attached to the first part of the statement, and not the second. You'd be as well writing the code like this:

Code: [Select]
p 9 > 3  #prints true
6 == 3   #prints nothing because there's no p

What is happening is that it reads it more like this:

Code: [Select]
(p 9 > 3) and (6 == 3)

First it prints the outcome of 9 > 3, which is true. And then it simply operates 6 == 3, which is does register as false, but because there isn't a 'p' it doesn't print anything.

So, the thing to remember is that you shouldn't treat 'and' and 'or' as evaluating many things at once. It's more like saying: 'do this' and then 'do this if the first succeeds'. If the first part fails, the bit after 'and' doesn't get processed.

At least that's my interpretation, but I think I have the understanding correct.

Here's something little I just wrote up and the results of them. If you can follow the understanding, then that's good.

Code: [Select]
def some_method(value)
  if value > 5
    p "true, #{value} is greater than 5"
    return true
  else
    p "false, #{value} is not greater than 5"
    return false
  end
end

some_method(10) and some_method(4)
#prints "true, #{value} is greater than 5" and then "false, #{value} is not greater than 5"

some_method(3) and some_method(6)
#prints "false, #{value} is not greater than 5" ONLY

some_method(8) or some_method(10)
#prints "true, #{value} is greater than 5" ONLY

some_method(3) or some_method(12)
#prints "false, #{value} is not greater than 5" and then "true, #{value} is greater than 5"

It's not that the tutorial is wrong, they've just missed something of pretty great importance due to the way they've gone about writing it (and not read up on what is actually going on under the code).

Take a read of this article here:

http://devblog.avdi.org/2010/08/02/using-and-and-or-in-ruby/

Spoiler for Additionally:
As an additional note to the guide you are using. When they talk about using 'boolean' values, you'll come to learn that this too isn't quite correct.

From an earlier post I wrote here: http://rmrk.net/index.php/topic,46655.msg540272.html#msg540272

Quote
Ruby doesn't have a Boolean object type. It has two types in place of that: TrueClass and FalseClass. When you use the keyword 'true' or 'false' it is a keyword that references an object of the respective type (true is a TrueClass, false is a FalseClass). When you come to checking the object type with the .is_a? method, you will have to check for it being a TrueClass object or a FalseClass one.

When you do something like this:

Code: [Select]
false_eval = (5 > 10)  # false_eval = false
p false_eval.class         # FalseClass
true_eval = (5 == 5)   # true_eval = true
p true_eval.class          # TrueClass

This very quickly shows that, even though you aren't creating any objects of the type FalseClass and TrueClass,  (5 > 10) returns a FalseClass object, which is then assigned to false_eval. The same happens even if you do:

Code: [Select]
false_eval = false
p false_eval.class

All 'false' is, is a reference to an object of FalseClass. Same for 'true'.

« Last Edit: January 18, 2013, 01:14:28 AM by LoganF »
(Why do I always feel like it's the end of the world and I'm the last man standing?)

**
Rep:
Level 46
Overlord in Training
Thank you for your very clear explanation. I'm beginning to grasp that the difference is that and,or,not are for control flow, where as && || are for evaluating expressions. It will be some time before I grasp them fluently I think. I will need to experiment heavily.

Also, I'm going to look at some other tutorials, since it left out that key bit of info.

However, and, or, not, can be used in combination with paranthesis,
p (3==3 and 4==3)
which means
p 3==3 && 4==3

I will probably come back to read this post several times.
As well as the links you provided.

Questions about this example: (I'm sorry, my spirit animal is a cat. :p )
Code: [Select]
def load_save_file
  if save_file_found
   #load save file data
    return true
  else
    return false
  end
end

load_save_file or raise "unable to load save file"

The main reason this doesn't work as is, is because the method(it's a method?) save_file_found
hasn't been defined yet, right?

so if load_save_returns false, it displays a string of text.



Code: [Select]
#So I think I understand most of it...but first off, I keep getting the truth value printed, wheras yours only prints the string.
# so def is used to create methods? And (value) is not a variable is it? I'm not that far advanced yet, I haven't learned methods.

def some_method(value)
  if value > 5
    p "true #{value} is greater than 5"
    return true
  else
    p "false #{value} is not greater than 5"
    return false
  end
end

p some_method(10) and some_method(4)
# will return true, and because it's true, it will then execute part two which is false.

p some_method(3) and some_method(6)
# because the first part is false it will not print anything else.

p some_method(8) or some_method(10)
#because the first one is false, it continues to search

p some_method(12) or some_method(3)
#because the first one is true, its already satisfied the conditions of 'or'

p some_method(2) or some_method(4) or some_method(11)
# returns true that 11 is greater than 5

p some_method(33) and some_method(443) and some_method(3)
# stops at saying 33 is true, but I don't know why. Until I added the next bit, then it went as 443 which is what I expected in the first place.

p " #{some_method(33)} and #{some_method(443)} "
# why does it only state it's truth value...because it is in the string? also, and isn't actually doing anything here right? I' guess i'll see...

p " #{some_method(33)} or #{some_method(443)} "

# so yeah, it's just printing or?

p " #{some_method(33)} #{some_method(443)} "


I'm sure I missed a lot. But that is what I've understood so far.

*
Rep:
Level 82
However, and, or, not, can be used in combination with paranthesis,
p (3==3 and 4==3)
which means
p 3==3 && 4==3

Not exactly. Just because there are parenthesis doesn't mean the code inside is reinterpreted a different way. p (3 == 3 and 3 == 5) still means just that. The difference is, that the p will print out the success state of the whole expression and not just p 3 == 3.

The reason that

Code: [Select]
p (9 > 2 and 6 == 3) #false

Is because the first evaluation succeeds, and is true. Because it is true, the 'and' is followed and the next expression is evaluated. Because 6 == 3 is false, the result that is printed is false because one of the expressions failed, and an 'and' is only true when all parts are true.

Code: [Select]
p 5 < 6 && 3 < 4 #true
p 5 < 6 && 3 < 2 #false
p 5 > 6 && 3 < 4 #false
p 5 > 6 && 3 < 2 #false

Only one of those 4 variations is true, because both must be true for an 'and' expression to be true (assuming 2 expressions inside). We could write it out as:

Code: [Select]
p (is_successful and is_successful) #true, both success = complete success
p (is_successful and is_not_successful) #false, only partial success, complete success required
p (is_not_successful and is_successful) #false, only partial success, complete success required
p (is_not_successful and is_not_successful) #false, no success/is a failure, complete success required

With the save file code, I should have added a comment to assume that save_file_found is some method or parameter that will result in the if statement succeeding or failing. As an example, it could hold a true or false result, meaning if it is true, then the if section is executed. If it's a false result then the else would be executed.

If the method doesn't exist, it won't compile anyway will that code.
(Why do I always feel like it's the end of the world and I'm the last man standing?)