If defined on var


#1

db =
Amalgalite::Database.new("/usr/local/vrep/repo/db/development.sqlite3")
table_exists = db.execute(“select name from sqlite_master where
type=‘table’ and tbl_name=‘derek’”)

if defined?(table_exists)
p “yes”
end
exit

Why does this print “yes”? There is no table called derek in my DB. In
fact it prints yes no matter what I type in for tbl_name.

My goal is to see if a table exists by testing the var holding the data
is true/defined or not. Will you help?

thank you
derek!


#2

Am Mittwoch 19 August 2009 04:22:18 schrieb Derek S.:

My goal is to see if a table exists by testing the var holding the data
is true/defined or not. Will you help?

true and defined are two very different things. Take this snippet as an
example:

x = 42
y = false
z = nil

Here the variables x, y and z are defined. The variables a, b and
foobarbaz
are not. In short: once you assign a value to a variable that variable
is
defined - no matter whether that value was true or not. If you want to
check
whether the value a variable holds is true or not, do that. Don’t use
defined?.
In your case you can just do if table_exists which even reads more
naturally.

HTH,
Sebastian


#3

Hi,
Am Mittwoch, 19. Aug 2009, 11:22:18 +0900 schrieb Derek S.:

table_exists = db.execute( …)

if defined?(table_exists)
p “yes”
end
exit

Why does this print “yes”?

irb(main):001:0> x = nil
=> nil
irb(main):002:0> defined? x
=> “local-variable”
irb(main):003:0> defined? y
=> “method”
irb(main):004:0> defined? z
=> nil
^^^
^^^^^
irb(main):005:0> y
ArgumentError: wrong number of arguments (0 for 1)
from (irb):5:in `y’
from (irb):5
irb(main):006:0>

Ugh, I did not know that `y’ is a method.

Be aware that `defined?’ is not an operator but examines the next
token.

Bertram


#4

Bertram S. wrote:

Ugh, I did not know that `y’ is a method.

Only if you “require ‘yaml’”

One other thing to note. Deciding whether something is a local variable
happens at parse time, independent of whether the line is actually
excuted or not. So:

if false
x = 123
end
p defined? x # “local_variable”
p x # nil


#5

Sebastian H. wrote:

Am Mittwoch 19 August 2009 04:22:18 schrieb Derek S.:

My goal is to see if a table exists by testing the var holding the data
is true/defined or not. Will you help?

true and defined are two very different things. Take this snippet as an
example:

x = 42
y = false
z = nil

Here the variables x, y and z are defined. The variables a, b and
foobarbaz
are not. In short: once you assign a value to a variable that variable
is
defined - no matter whether that value was true or not. If you want to
check
whether the value a variable holds is true or not, do that. Don’t use
defined?.
In your case you can just do if table_exists which even reads more
naturally.

HTH,
Sebastian

Hey Seb,

Your advice is always welcome and respected. But Iam still confused,
see below.
The table derek does NOT exist of course.

table_exists = db.execute(“select name from sqlite_master where
type=‘table’ and tbl_name=‘derek’”)

if table_exists
p “yes”, “#{table_exists}”
end
if table_exists == “”
p “yes”
else
p “no”
end

OUTPUT

$ ruby mail_log_miner.rb
“yes”
“”
“no”

With a table that does exist using same if clauses.

ruby mail_log_miner.rb
“yes”
“lines”
“no”


#6

On Aug 19, 2009, at 19:49, Derek S. wrote:

if table_exists == “”
p “yes”
else
p “no”
end

OUTPUT

$ ruby mail_log_miner.rb
“yes”

The variable “table_exists” is not nil and not false. It is probably
an empty array of rows, if you’re using the sqlite database adapter.

“”

The stringified version of the variable “table_exists” is an empty
string. This is what you would expect if “table_exists” is an empty
array:

irb(main):001:0> [].to_s
=> “”

Putting “#{foo}” inside a string basically says "call .to_s on the
object and concatenate the results with the beginning and end of this
string. In other words:

“#{table_exists}”

is the same as

“” + table_exists.to_s + “”

If you want to see a better representation of an object, just call “p
object” or “puts object.inspect”

“no”

No, "table_exists’ is not literally an empty string. You wouldn’t
expect that, however, since db.execute doesn’t return strings, but
arrays.

With a table that does exist using same if clauses.

ruby mail_log_miner.rb
“yes”

Yes, table_exists is not false and not nil.

“lines”

“#{table_exists}” is “lines”, i.e. table_exists.to_s is lines.

table_exists is probably [“lines”], i.e. an array with 1 element, the
string “lines”.

irb(main):002:0> [“lines”].to_s
=> “lines”

“no”

No, “table_exists” is not literally an empty string.

I think what you want is more along these lines:

Don’t call it “table_exists” because that implies the value is a

boolean, when in fact it will be an array

table_array = db.execute(“select name from sqlite_master where
type=‘table’ and tbl_name=‘derek’”)

if table_array.size > 0
p “yes”, table_array
end

if not table_array.empty?
p “yes”
else
p “no”
end

Ben


#7

I think what you want is more along these lines:

Don’t call it “table_exists” because that implies the value is a

boolean, when in fact it will be an array

table_array = db.execute(“select name from sqlite_master where
type=‘table’ and tbl_name=‘derek’”)

if table_array.size > 0
p “yes”, table_array
end

if not table_array.empty?
p “yes”
else
p “no”
end

Ben

Amen Ben! I understand completely. Thank you!
Im still new to Ruby, coming from Perl.