Trying to write a program interactively which can take inputs from command line as an expression or attributes like -
irb : 3+2
Should evaluate to => 5
Attribute
irb : abc = 1
=> 1
irb : jkl(or def) = 1
=> 1
irb : abc + def
=> 2
Also the evaluation should take place once user inputs blank line.
My efforts : I created a method attr_accessor which iterates through the array of *secret passed to it, and calls define_method on each attr, creating an instance variable getter and setter for each attribute.
Part of code working : I made a success in evaluating the expressions and returning string values.
irb : 3+2 Should evaluate to => 5
irb : True => True
But still stuck with evaluation of assignment to attributes and unable to dynamically store those values in my interactive irb. Below expected results are not working : Attribute
irb : abc = 1
=> 1
irb : def = 1
=> 1
irb : abc + def
=> 2
Note - I don't want to use "require 'irb' " or " "require 'pry'". Can this be achieved with simple ruby code ?
My Solution:
class Demo
def self.attr_accessor(*secret)
secret.each do |attr|
define_method(attr) { instance_variable_get("@#{attr}") }
define_method("#{attr}=") { |val| instance_variable_set("@#{attr}", val) }
end
get_binding
end
def self.method_new(input)
@object = attr_accessor(input)
end
def self.method(secret)
@object = Regexp.new(/\A[\d+\-*\/=. ]+\z/).match(secret.to_s) ? eval(secret) : "Invalid expression"
get_binding
end
def self.simple_method(secret)
@object = secret
get_binding
end
def self.get_binding
binding
end
end
user_input = ''
until user_input == 'q' do
user_input = gets.chomp
if user_input =~ /^.*=.*$/
b2 = Demo.method_new(*user_input)
puts eval('@object', b2)
elsif user_input =~ /\A[\d+\-*\/=. ]+\z/
b3 = Demo.method(user_input)
puts eval('@object', b3)
else
b4 = Demo.simple_method(user_input)
puts eval('@object', b4)
end
end
Expected Result:
irb : 3+2
#note - each result evaluated after user enters blank line
Should evaluate to => 5
Attributes ---
irb : abc = 1
#note - each result evaluated after user enters blank line
=> 1
irb : def = 1
#note - each result evaluated after user enters blank line
=> 1
irb : abc + def( or jkl)
#note - each result evaluated after user enters blank line
=> 2
Actual Result : Output is "Invalid expression" for all other inputs except expressions and simple strings.
defis a keyword - steenslag