3

I have this code that's working:

  case index
   when "Books"
     @reading_img = res.items.first.get_hash('MediumImage')["URL"] # don't show an image
     @reading_link = create_amz_url(search, asin)        

     tempy = @nowreading.content.match(/#nowreading.*/).to_s.gsub("#nowreading",'') # strips away the #nowreading tag
     @nowreading.content = tempy.match(/#{search}.*/).to_s.gsub("#{search}", @reading_link) 
     # replaces the book title (passed in as variable 'search') with the URL'ed title

   when "Music"
     @listening_img = res.items.first.get_hash('MediumImage')["URL"] # don't show an image
     @listening_link = create_amz_url(search, asin)        

     tempy = @nowlistening.content.match(/#nowlistening.*/).to_s.gsub("#nowlistening",'') # strips away the #nowreading tag
     @nowlistening.content = tempy.match(/#{search}.*/).to_s.gsub("#{search}", @listening_link) 
     # replaces the song title (passed in as variable 'search') with the URL'ed title       

   end

I need to repeat this for many, many categories. I tried something like this to DRY the code but it didn't work:

     def get_img_and_links(act, res, search, asin)
        '@'+act+'ing_img' = res.items.first.get_hash('MediumImage')["URL"] # don't show an image
        '@'+act+'ing_link' = create_amz_url(search, asin)        

        tempy = '@now'+act+'ing'.content.match(/#now"#{act}"ing.*/).to_s.gsub("#now#{act}ing",'') # strips away the #nowreading tag
        '@now'+act+'ing'.content = tempy.match(/#{search}.*/).to_s.gsub("#{search}", '@'+act+'ing_link') 
        # replaces the book title (passed in as variable 'search') with the URL'ed title
     end

Essentially, I was trying to create a function that took an "act" (e.g., "read", "listen", etc) and have the variables within that function be dynamic. Can this be accomplished? If so, how?

2
  • How many of those instance variables are used outside the method in question? Commented Jul 14, 2011 at 6:26
  • All of them. They're used to update different content boxes (e.g., one for reading, listening, etc.) on a user's page. Commented Jul 14, 2011 at 13:39

4 Answers 4

6

Look up instance_variable_set here: http://ruby-doc.org/core/classes/Object.html. It's what you need to dynamically create these variables.

instance_variable_set "@#{act}ing_img".to_sym, res.items.first.get_hash('MediumImage')["URL"]

And so on...

Sign up to request clarification or add additional context in comments.

Comments

4

Good looking out trying to dry up your code. I would definitely use some hashes there instead of instance variables. Then you can use the key as the action. Just a thought.

2 Comments

+1 Hashes are pretty much always better than dynamic variable names.
Great suggestion; I ended up using this instead. The Blah.to_sym made it too damn hard to read. I gave the points to Steve Ross, however, because he technically answered my question.
1

IMPO, I think you should use more generic variables. Although the creating variables are supported by ruby, it will make your code hard to read

my suggestion is having some generic names like

@img (instead of reading_img, listing_img etc..) @link (instead of reading_link, listing_link etc..) and something like @content, because as your login at a given time only one will be selected and this wouldn't be a problem

Again, this is what i understood from the code you posted and correct me if I'm wrong

cheers

sameera

Comments

1

you should do something like this:

def setup
  @reading_img    = get_img(whatever)
  @reading_link   = get_link(whatever)
  @listening_img  = get_img(whatever)
  @listening_link = get_link(whatever)
end

def get_img(whatever)
  ...do stuff and return stuff...
end

def get_link(whatever)
  ...do stuff and return stuff...
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.