0

How to convert a string like this

    "6.months" => 6.months
    "6.years" => 6.years

I know how to split these characters but I don't know how to make the string as an object of the date class.

Thanks

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
Ruel Nopal
  • 385
  • 3
  • 15
  • 1
    What do you `6.months` expect to be? A string without quotes? A method call (there is no `months` method on integer)? Where are the strings coming from? – spickermann Aug 12 '20 at 12:41
  • I have a string "6.months" i want it to be `6.months` so i can add the date like this `Date.today + 6.months` – Ruel Nopal Aug 12 '20 at 12:43
  • 1
    If you're using Rails or just ActiveSupport use the proper tags, Ruby alone does not have a `#months` method for integers. – Viktor Aug 12 '20 at 12:45

2 Answers2

4

Maybe something like this?

require "active_support/core_ext/integer/time"

'6.months'.split('.').then{ |n, t| n.to_i.public_send t }

#=> 6 months

So:

Date.today + '6.months'.split('.').then{ |n, t| n.to_i.public_send t }

Or patching the String class:

module MyStringPatch
  def to_integer_time
    self.split('.').then{ |n, t| n.to_i.public_send t }
  end
end

String include MyStringPatch

Date.today + '6.months'.to_integer_time

Or if you trust the evil eval (see comments), you can also just do:

Date.today + eval('6.months')

By the way, as pointed by @AlekseiMatiushkin

If it comes from the user input, #public_send might also be dangerous

iGian
  • 11,023
  • 3
  • 21
  • 36
2

If you are completely sure you have a valid object of ActiveSupport::Duration, you can do something like the following:

amount, time_span = '6.months'.split('.')
duration = amount.to_i.public_send(time_span)

Date.today + duration

amount is the String 6 and time_span is the String months. duration is the ActiveSupport::Duration 6 months. The result will be the present day in 6 month, which is a Date

David Seeherr
  • 121
  • 1
  • 6