ID:1509780
 
(See the best response by Pirion.)
Problem description: So I've seen developers/helpers on here at times use procedures when using if(). I wondered why?

So I thought I'd give it a shot and learn/see how it works. So am I doing it correctly? I believe I am but I'm quite unsure of myself when it comes to DM.

Anyone wanting to adapt on the profanity code may do so freely, though I imagine there's much better around these parts.

Also note, I realise some of these may be pointless in certain situations.

Code:
mob/var/
test = 5

mob/verb/test()
if(test1(src))
world<<"correct!"

var/test2 = 5

proc
test1(mob/m)
return m.test == test2


//checking to see how it would work with variables in the verb.
mob/verb/testy()
var/T = 5
if(test1(T))
world<<"correcty!"

var/testy2 = 5

proc
testy1(T)
return T == testy2

//test three for profanity

var/swearcheck = 1

mob/verb/profanity()
var/naughty = pick("naughty", "nice","santa")

if(swearcheck)
if(profanity_check(naughty))
world<<"BAD BOY/GIRL/IT"

else if(santa_check(naughty))
world<<"mmmmmm ho ho ho ;)"

else
world << "Good."

var/list/profanity = list("naughty")

proc
profanity_check(naughty)
return profanity.Find(naughty)

santa_check(naughty)
return naughty == "santa"


Wow that's a mess to read.

test1() will return false because you're not passing an M.
If swearcheck is always 1 there's no real point to checking if it's true.
Everything else looked fine at a glance but you're doing all of these assumptions and I'm not entirely sure what the point of all this is.
I think you're missing the point Lugia, this would never be used in real situations. It was more of a can I do it type thing, since I knew nothing about it.

I just realised I should be using usr in test1, but it worked just fine with src. It's nearly 6 am here, that's my excuse.

The profanity one could possibly be useful in the future, so swearcheck could be on or off. Say I have multiple verbs to talk with, OOC, say, whisper, etc etc.
There's no reason to make convoluted code to test it though. Making code as complex as possible defeats the purpose. You're not even trying to account for style. And I'd understand if you were trying to do something complex, but you're literally TRYING TO FIGURE OUT IF STATEMENTS AND RETURN VALUES.

if statements are simple. Do the next block if the statement is true, don't do it if otherwise. return statements are what replace method calls in line. Flow of control.

var/num1 = 1
var/num2 = 10

verb
CheckNums(var/first, var/second)
if(first == second)
src << "yay"
return
src << "boo" // not equal
return

CheckNumProc()
if(src.CheckProc(num1, num2))
// Flow of control switches to proc. The return value will be evaluated in the if
src << "yay"
return
src << "boo"
return

proc
CheckProc(var/first, var/second)
if(first == second)
return 1 // if() will be true
return 0 // if() will be false
See this is why I created the topic. I already knew how to use if statements, I was just trying to work out why people did things certain ways.

Everything I do on BYOND right now is just me taking baby steps and learning little by little.

I misinterpreted a few pieces of code I saw and tried to create my own variation using similar techniques. But, no harm in experimentation.
The comparison operators shouldn't be considered any differently from the other operators.

A == B is like x + y in that == and + are both operators (binary, to be exact, as they both take 2 inputs).

Operators return a value (like procs do) given certain input(s).
if(doStuff()) // do some stuff
if(!doStuff()) // this will never evaluate true

proc/doStuff()
return 1


the proc evaluates to whatever it returns, and a proc always returns. Thats about all there is to it; What does the proc evaluate to? Well, whatever you're returning in the proc :)
So say for example, I had a level code and I needed to use it more than one situation. It could be used as such in the example below?

if(level()) // do some stuff


proc/level()
if(src.experience >= src.max_experience)
src.level++
src.experience = 0
return 1
else
return 0
the else return in that case is redundant
The else isn't really needed there. Should the if statement not match, it'll run whatever follows. Should the if statement match, it runs what's intended, until it hits return 1.

if(level()) // do some stuff


proc/level()
if(src.experience >= src.max_experience)
src.level++
src.experience = 0
return 1
return 0
In response to Rickoshay
The proc must also be defined in a scope where src has those variables.
Gotcha, I had the else there because I did have more lines of code but seemed kind of pointless.

Also I changed the profanity example I did, I assume this is a bit better?

All this help is much appreciated by the way, if I could up vote you all I would.

var/profanity_check = 1
var/max_warnings = 3 //this would be better off as a constant variable? Unless i wanted possible admins to change it?
var/list/profanity = list("naughty")

mob/var/warnings = 0

mob/verb/Say(T as text)
if(profanity_check)
if(usr.profanity(T))
if(usr.warn_check())
usr<<"You have been banned."
//ban code
return//to stop the refrain from bad language line.
usr<<"Please refrain from bad language."
return

world << "[usr] says: [T]"

mob/proc
warn_check()
if(src.warnings >= max_warnings)
return 1

profanity(T)
for(var/A in profanity)
if(findtext(A, T))
src.warnings++
return 1
return 0
Best response
warn_check is redundant in your example.

src.warnings >= max_warnings is a boolean operation, which means it returns a 1 if true and a 0 if false.

mob/verb/bool_check()
world << 3 <= 3
world << 3 <= 2

If you wanted to encapsulate this behavior (for reuse), then you would put the equation in the return.

mob/proc
warn_check()
return src.warnings >= max_warnings


return . (which is assumed if you do not specify a return) is null and evaluates to false on custom procedures (unless overwritten by . = blah), so no need for an explicitly give a 0 upon a return, unless you're expecting a number to always come back.

Combining your evaluations, rather than doing nested loops allows you to eliminate the returns, and make code look quite a bit neater. For example:

mob/verb/Say(T as text)
if(profanity_check && usr.profanity(T)) //short circuit here - if there is a profanity_check, then check it, otherwise the procedure will be skipped.
if(warn_check())
usr<<"You have been banned."
//ban code
else
usr<<"Please refrain from bad language."
else //if it was tagged as profane, this will never be run - eliminating the need for explicit returns.
world << "[usr] says: [T]"


That is however preference - there are many ways to write the same thing.