3

I'm preparing a string that will be eval'ed. The string will contain a clause built from an existing Array. I have the following:

def stringify(arg)
    return "[ '" + arg.join("', '") + "' ]" if arg.class == Array
    "'#{arg}'"
end

a = [ 'a', 'b', 'c' ]
eval_str = 'p ' + stringify(a)
eval(eval_str)

which prints the string ["a", "b", "c"].

Is there a more idiomatic way to do this? Array#to_s doesn't cut it. Is there a way to assign the output from the p method to a variable?

Thanks!

3 Answers 3

8

inspect should accomplish what you are wanting.

>> a = %w(a b c)
=> ["a", "b", "c"]
>> a.inspect
=> "[\"a\", \"b\", \"c\"]"
Sign up to request clarification or add additional context in comments.

1 Comment

inspect is perfect. Thanks! @dylanfm, yes eval was for context only.
0

I may be misunderstanding you, but does this look better at all?

>> a = %w[a b c]
=> ["a", "b", "c"]
>> r = "['#{a.join("', '")}']"
=> "['a', 'b', 'c']"
>> r.class
=> String

I suppose I'm confused by the need for eval, unless that's a part of something outside of what I see here.

Comments

0

Is there a way to assign the output from the p method to a variable?

p (the same as puts) writes it's argument to $stdout and returns nil. To capture this output, you need to temporarily redefine $stdout.

require 'stringio'

def capture_stdout
  old = $stdout
  $stdout = StringIO.new(output = "")
  begin
    yield
  ensure 
    # Wrapping this in ensure means $stdout will 
    # be restored even if an exception is thrown
    $stdout = old
  end
  output
end

output = capture_stdout do
  p "Hello"
end

output # => "Hello"

I am not sure why you need this in the example, you could just do

output = stringify(a)

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.