if defined on var

D

Derek Smith

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!
 
S

Sebastian Hungerecker

Am Mittwoch 19 August 2009 04:22:18 schrieb Derek Smith:
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
 
B

Bertram Scharpf

Hi,
Am Mittwoch, 19. Aug 2009, 11:22:18 +0900 schrieb Derek Smith:
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
 
B

Brian Candler

Bertram said:
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
 
D

Derek Smith

Sebastian said:
Am Mittwoch 19 August 2009 04:22:18 schrieb Derek Smith:

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"
 
B

Ben Giddings

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"

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, "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.

"#{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, "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
 
D

Derek Smith

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top