TLDR: Unfortunately, your examples are flawed, because you have chosen a name for your variable that clashes with existing method from core ruby.
As @SteveTurczyn mentioned a few minutes ago, if variable is not known before the line with the conditional, it's interpreted as a method call.
Let's explore some machine code, shall we? Important lines are commented.
puts "Am i a string? #{myvar}" if myvar = "Im a confused string"
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, keyword: 0@3] s1)
[ 2] myvar
0000 trace 1 ( 2)
0002 putstring "Im a confused string"
0004 dup
0005 setlocal_OP__WC__0 2
0007 branchunless 22
0009 putself
0010 putobject "Am i a string? "
0012 putself
0013 opt_send_simple <callinfo!mid:myvar, argc:0, FCALL|VCALL|ARGS_SKIP> # call method myvar
0015 tostring
0016 concatstrings 2
0018 opt_send_simple <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>
0020 leave
0021 pop
0022 putnil
0023 leave
And when variable is declared beforehands
myvar = "Im totally a string"
puts "Am i a string? #{myvar}" if myvar = "Im a confused string"
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, keyword: 0@3] s1)
[ 2] myvar
0000 trace 1 ( 1)
0002 putstring "Im totally a string"
0004 setlocal_OP__WC__0 2
0006 trace 1 ( 2)
0008 putstring "Im a confused string"
0010 dup
0011 setlocal_OP__WC__0 2
0013 branchunless 27
0015 putself
0016 putobject "Am i a string? "
0018 getlocal_OP__WC__0 2 # Read variable value
0020 tostring
0021 concatstrings 2
0023 opt_send_simple <callinfo!mid:puts, argc:1, FCALL|ARGS_SKIP>
0025 leave
0026 pop
0027 putnil
0028 leave
Now, the problem with your code is that p
is a method that exists. In case you didn't know about it, p foo
is equivalent to puts foo.inspect
. Similarly to puts
, it accepts flexible number of arguments (even zero arguments) and returns nil
.
puts "Am i a string? #{p}" if p = "Im a confused string"
^ call method `p` here
But
p = "foo" # Shadow existing method `p`
puts "Am i a string? #{p}" if p = "Im a confused string"
^ get local var
if you wanted to also call the method `p`, you'd have to just through some extra hoops
or just rename the variable.