0

This is primarily a Ruby question but I've tagged it with watir-webdriver because the example includes watir-webdriver code in the hopes that it will improve clarity.

I have a class that can both retrieve and update data found on a web page. That data gets stored in instance variables of the class.

The class includes a method that will either use the existing instance variable value to update a select list on the web page, or, if the instance variable is nil, it will get the select list's value and store it in the instance variable.

The method currently looks like this:

def get_or_select!(inst_var_sym, select_list)
  value = instance_variable_get inst_var_sym
  if value==nil
    instance_variable_set inst_var_sym, select_list.selected_options[0].text
  else
    select_list.select value
  end
end

That works, but I am wondering if there is a way to write the method such that it can be applied directly to the instance variable (and not a symbol matcher for the instance var) and take, as its single parameter, the select_list object.

In other words, what currently looks like this:

get_or_select!(:@instance_variable, select_list)

I would like to look like this:

@instance_variable.get_or_select!(select_list)

Is this even possible?

Abe Heward
  • 515
  • 3
  • 16
  • Sure; add the method to whatever class(es) `@instance_variable` is. – Dave Newton Jan 29 '13 at 21:15
  • No, you can't set instance variable this way. – mikdiet Jan 29 '13 at 21:19
  • @Dave, the method is already in that class. However, when I try setting it up that way I get a missing_method error because `@instance_variable` is either a `NilClass` object or else a `String`, and neither of those classes know about `.get_or_select!`, sadly (and even if they did, they wouldn't know about my data class's instance variables). – Abe Heward Jan 29 '13 at 21:26

1 Answers1

1

New answer: Since the variable doesn't exist until you define it, you cannot call methods on it. The calling class will have to set it. You can just do a simple if check.

#In the calling class, not the variable class  
  if @instance_variable       # If it is defined, this is true
    returned_list = select_list.select @instance_variable.value # Gets the selected list 
  else
    @instance_variable = instance_variable_set inst_var_sym, select_list.selected_options[0].text
  end

OLD answer below: Could you not use the conditional assignment? http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators#1._Assignment

x = find_something() #=>nil
x ||= "default"      #=>"default" : value of x will be replaced with "default", but only if x is nil or false
x ||= "other"        #=>"default" : value of x is not replaced if it already is other than nil or false

so for this it would be something like...

instance_variable_get inst_var_sym ||= instance_variable_set inst_var_sym, select_list.selected_options[0].text
DouglasCodes
  • 243
  • 2
  • 10
  • That definitely cleans things up, so thanks! But it still leaves me with two parameters in the method. It just seems like I'll be stuck with that. – Abe Heward Jan 29 '13 at 21:49
  • Actually, I lied. It doesn't clean things up because the conditional assignment as written doesn't allow for setting the select list to the value in the inst_var if it's not nil. Oh well. – Abe Heward Jan 29 '13 at 23:34
  • I'll check it out again when I get back from work. Maybe I'll put my glasses on this time. – DouglasCodes Jan 30 '13 at 19:57