Question about reflection

G

gmalicki

These two snippits of code both do the same thing. One of them uses
reflection and one does not. The one that uses reflection is a line
shorter so to me it feels like a better choice. In the #ruby-lang IRC
channel people told me to "use reflection only when you have to". Is
that a sane general rule to stick with for Ruby programming ? Is there
anything wrong with using reflection in this case ? Are there any
upsides or downsides to either approach ?

# NIL LOCAL VAR TECHNIQUE
query = nil
query = "foo" if config[:scope] == :page
query = "bar" if config[:scope] == :domain
raise BrokenConfig if query.nil?


# REFLECTION TECHNIQUE
query = "foo" if config[:scope] == :page
query = "bar" if config[:scope] == :domain
raise BrokenConfig unless Kernel.local_variables.member?( "query" )

thanks
 
R

Robert Klemme

These two snippits of code both do the same thing. One of them uses
reflection and one does not. The one that uses reflection is a line
shorter so to me it feels like a better choice. In the #ruby-lang IRC
channel people told me to "use reflection only when you have to". Is
that a sane general rule to stick with for Ruby programming ? Is there
anything wrong with using reflection in this case ? Are there any
upsides or downsides to either approach ?

Reflection is usually slower. And yes, IMHO you should use it only if
you actually need meta programming capabilities.
# NIL LOCAL VAR TECHNIQUE
query = nil
query = "foo" if config[:scope] == :page
query = "bar" if config[:scope] == :domain
raise BrokenConfig if query.nil?


# REFLECTION TECHNIQUE
query = "foo" if config[:scope] == :page
query = "bar" if config[:scope] == :domain
raise BrokenConfig unless Kernel.local_variables.member?( "query" )

Don't do either of the two. There are far better idioms available:

query = case config[:scope]
when :page
"foo"
when :domain
"bar"
else
raise BrokenConfig
end

QUERY_MAP = Hash.new {|h,k| raise BrokenConfig, k}.update(
:page => "foo",
:domain => "bar"
).freeze

....

query = QUERY_MAP[config[:scope]]

Kind regards

robert
 
A

Andrew Johnson

These two snippits of code both do the same thing. One of them uses

No, they do not do the same thing: the first sets a local
variable, the second may or may not set a local variable.
reflection and one does not. The one that uses reflection is a line
shorter so to me it feels like a better choice. In the #ruby-lang IRC

Shorter does not neccessarily equate to better -- strive for
clarity not shortness. Besides, your first example (although
one line longer) is actually some 20+ characters shorter!

Here's an even longer version (line-wise) that is even shorter
(character-wise):

query = case config[:scope]
when :page: "foo"
when :domain: "bar"
else raise BrokenConfig
end
channel people told me to "use reflection only when you have to". Is
that a sane general rule to stick with for Ruby programming ? Is there
anything wrong with using reflection in this case ? Are there any

The general rule I'd stick to for using reflection is simple: use
reflection for tasks that require reflection; not to accomplish
something indirectly.

The general rule I'd suggest for shorter code: Be concise in
saying what you mean, not just saying something short that
happens to achieve your goal.

Lastly, do you really intend on using your 'query' variable later
in the code, or is it just a synthetic variable to query the
state of the config hash? If its purely synthetic then drop it
and just query the config hash.

cheers,
andrew
 

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

Staff online

Members online

Forum statistics

Threads
474,206
Messages
2,571,068
Members
47,674
Latest member
scazeho

Latest Threads

Top