Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dentaku + ruby-units: Let dentaku defer some or all operations to custom class #297

Open
abhinavc opened this issue Aug 6, 2023 · 0 comments

Comments

@abhinavc
Copy link

abhinavc commented Aug 6, 2023

Hi @rubysolo,
First, thanks for a wonderful gem. It is just what I was looking for.

I have, however, have run into a tiny issue. I'm trying to do calculations w/ physical quantities - expressed using ruby-units gem. ruby-units overloads +, -, * and / operators - amongst others.

Everything works fine - except /. So, something like

calc = Dentaku::Calculator.new 
a = Unit.new(1, 'N')
b = Unit.new(1, 'm^2') 
pressure = calc.evaluate('a/b', a: a, b: b) # should return 1 N/m^2

throws a BigDecimal: invalid value for BigDecimal(): "1 m^2" (ArgumentError) exception.
But if I comment out def value in class Division < Arithmetic (ast/arithmetic.rb)

class Division < Arithmetic
      def operator
        :/  
      end 

=begin
      def value(context = {}) 
        y = right.value(context)
        r = decimal(cast(right.value(context)))
        raise Dentaku::ZeroDivisionError if r.zero?

        cast(cast(left.value(context)) / r)
      end
=end 

      def self.precedence
        20  
      end 
end 

then dentaku does not try to convert the value and ruby-units does the actual calculation .

Hence I was wondering if dentaku could be configured to defer calculations to a user-defined custom class. Maybe have an config/initializers/dentaku.rb with either of the following options:

  1. config.use_user_class true (default = false) -> dentaku wouldn't even try to do BigDecimal conversion, or
  2. config.use_classes [<list of class names>] -> dentaku will first try these and if operator fails, then defer to it's own default behaviour

The onus of overloading operators would be on the user class

I've only done a cursory reading of the code. You may have a more robust alternative to offer. Nevertheless, if this could be done formally, then I wouldn't have to continue with my hack.

Thanks
Abhinav.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant