3

I'm trying to make this simple method return a value related to the name of its input. For instance if I give the method "people_array" it should return "people_array_of_arrays."

If I were using the method in IRB I would get something like:

people_array = ["George\tMichael", "Kim\tKardashian", "Kanyne\tWest"]
=> ["George\tMichael", "Kim\tKardashian", "Kanyne\tWest"]
make_array_of_arrays(people_array)
=> people_array_of_arrays
people_array
=> ["George\tMichael", "Kim\tKardashian", "Kanyne\tWest"]
people_array_of_arrays
=> [["George", "Micahel"], ["Kim", "Kardashian"], ["Kayne", "West"]]

I have written this so far, but have not been able to figure out how to return a nicely named array of arrays. All I could think of was string interpolation but that isn't exactly what I need.

def make_array_of_arrays(array)
    formatted_array = []
    array.each do |feed|
        mini_array = feed.split("\t")
        formatted_array.push(mini_array)
    end
    #{array}_of_arrays = formatted_array
end

I saw there was a method variablize, but that returns an instance variable which isn't exactly what I want. Any pointers?

1
  • 1
    Well, we have map method for what you've done in the second part of your question. But still, I do not quite understand what's your problem? Do you want to set instance variables, such as @Kardashian = 'Kim' ? Commented Oct 26, 2012 at 21:14

4 Answers 4

3

I do not think that it can be easily done. Suppose you were able to define a local variable in some way within the method definition. But the scope of that local variable is limited to the method definition. So the moment you go outside of the method definition, the local variable name is gone. So in order to do it, you have to somehow get the binding information of the environment outside of the method definition, and define a local variable within that. I do not know if that is possible.

With instance variables, things get a little easier using instance_variable_set, but I am not sure how to implement it fully. First of all, getting the name of the original variable is tricky.

And what you are trying to do is not the right approach. You should think of different ways.


I think the best you can do is to use an instance variable instead of a local variable, and also give the name of the variable explicitly instead of the array itself:

def make_array_of_arrays(variable_name)
  array = instance_variable_get("@#{variable_name}")
  # Your code here
  instance_variable_set("@#{variable_name}_of_arrays", formatted_array)
end

@people_array = ["George\tMichael", "Kim\tKardashian", "Kanyne\tWest"]
make_array_of_arrays(:people_array)
@people_array_of_arrays
#=> [["George", "Micahel"], ["Kim", "Kardashian"], ["Kayne", "West"]]


This also might be useful.

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

2 Comments

One way to do that would be using regex magic, such as /(?<given_name>)\t(?<surname>)/ =~ 'Kim\tKardashian', which should set given_name and surname local variables, but of course, that's not from inside a method call.
@BorisStitnicky The OP does not want to set the names of the variables to given_name or surname.
2

No need for meta-programming (unless I misunderstand your question). Simply return your formatted array:

def make_array_of_arrays(array)
    formatted_array = []
    array.each do |feed|
        mini_array = feed.split("\t")
        formatted_array.push(mini_array)
    end
   formatted_array
end

Then you can assign the return value to whatever name you want:

people_array_of_arrays = make_array_of_arrays(people_array)

Note, you can use map to simplify your make_array_of_arrays method:

def make_array_of_arrays(array)
    array.map do |feed|
        feed.split("\t")
    end
end

7 Comments

:))) Can something this obvious be an answer?
It's kind of a poorly asked question... I'm not even sure ovatsug25 knows what he's looking for.
@AnthonyDeSimone I don't think so. The question is clear if you have the ability to read things carefully. What the OP is trying to achieve is impractical, though.
@sawa, I understand functionally what he wants to happen. But the exact implementation he's asking for is.. exotic?
or array.map(&:split), in this particular case.
|
2

The big problem here is there's no good way to access the name of a variable.

Barring that and building on Sean Vieira's addition, you could do some eval magic to get this:

def make_array_of_arrays(array, array_name)
    new_array = array.map { |feed| feed.split("\t") }

    eval("def #{array_name}_of_arrays; return #{new_array}; end")
end

This basically creates a function for your *_of_arrays line that returns the array you're looking for.

If you could find a way to get the name of the variable, you'd have everything you want. Not that I really officially endorse this method. And I can't for the life of me figure out why you'd want to do this. It's very unidiomatic, and will be confusing for anyone looking at that chunk of code.

1 Comment

I just realized you can also get the name of your variable with some more eval magic and the Kernel.binding method. But then you're just really getting yucky.
0

This is not easy nor advisable.

Think of Ruby Objects as people (you and me) communicating by phone (phonenumbers being object_id's). Imagine I am in your list of phonenumbers under the name (variable) 'sTeEnSlAg' , and also under 'steenslg'. Then you phone me and ask "Please give me the name you are registered under on my phone, post-fixed with "_of_arrays".

What do you think would be the polite version of my answer?

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.