Skip to content

Commit f6970c4

Browse files
committed
init
0 parents  commit f6970c4

File tree

16 files changed

+303
-0
lines changed

16 files changed

+303
-0
lines changed

.github/workflows/main.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: Ruby
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
pull_request:
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
name: Ruby ${{ matrix.ruby }}
14+
strategy:
15+
matrix:
16+
ruby:
17+
- '3.2.0'
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: Set up Ruby
22+
uses: ruby/setup-ruby@v1
23+
with:
24+
ruby-version: ${{ matrix.ruby }}
25+
bundler-cache: true
26+
- name: Run the default task
27+
run: bundle exec rake

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/.bundle/
2+
/.yardoc
3+
/_yardoc/
4+
/coverage/
5+
/doc/
6+
/pkg/
7+
/spec/reports/
8+
/tmp/

.rubocop.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
AllCops:
2+
TargetRubyVersion: 3.0
3+
4+
Style/StringLiterals:
5+
EnforcedStyle: double_quotes
6+
7+
Style/StringLiteralsInInterpolation:
8+
EnforcedStyle: double_quotes

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## [Unreleased]
2+
3+
## [0.1.0] - 2024-03-23
4+
- Initial release

Gemfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
3+
source "https://rubygems.org"
4+
5+
# Specify your gem's dependencies in expressive.gemspec
6+
gemspec
7+
8+
gem "rake", "~> 13.0"
9+
10+
gem "minitest", "~> 5.16"
11+
12+
gem "rubocop", "~> 1.21"

LICENSE.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2024 Omkar Moghe
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Expressive
2+
3+
A simple and flexible Ruby library to build and evaluate mathematical or other expressions.
4+
5+
## Installation
6+
7+
Install the gem and add to the application's Gemfile by executing:
8+
9+
$ bundle add expressive
10+
11+
If bundler is not being used to manage dependencies, install the gem by executing:
12+
13+
$ gem install expressive
14+
15+
## Usage
16+
17+
### Models
18+
19+
#### Scalar
20+
21+
A `Scalar` is the simplest object that can be evaluated. It holds a single `value`. When used in an `Expression`, this `value` must respond to the symbol (i.e. support the method) defined by the `Expression#operator`.
22+
23+
```ruby
24+
Scalar.new(1)
25+
```
26+
27+
#### Variable
28+
29+
A `Variable` represents a named value stored in the `Environment`. Unlike `Scalars`, `Variables` have no value until they are evaluated by an `Environment`. Evaluating a `Variable` that isn't present in the `Environment` will result in a `MissingVariableError`.
30+
31+
```ruby
32+
Variable.new("variable_a")
33+
```
34+
35+
#### Expression
36+
37+
An expression represents 2 or more `operands` that are reduced using a defined `operator`. The `operands` of an `Expression` can be `Scalars`, `Variables`, or other `Expressions`. All `operands` must `respond_to?` the method defined by the `operator`.
38+
39+
And `Expression` can store its result back into the `Environment` by defining an `output`.
40+
41+
```ruby
42+
# addition
43+
Expression.new(:+, Scalar.new(1), Scalar.new(2))
44+
45+
# multiplication
46+
Expression.new(:*, Variable.new("variable_a"), Scalar.new(2))
47+
48+
# storing output
49+
Expression.new(:+, Scalar.new(1), Scalar.new(2), output: "one_plus_two")
50+
```
51+
52+
#### Environment
53+
54+
The `Environment` holds state in the form of a `variables` hash and can evaluate `Expressions`, `Scalars`, and `Variables` within a context. The environment handles updates to the state as `Expressions` run.
55+
56+
```ruby
57+
environment = Environment.new(
58+
"variable_a" => 1,
59+
"variable_b" => 2,
60+
)
61+
62+
environment.evaluate(Variable.new("variable_a"))
63+
#=> 1
64+
65+
environment.evaluate(
66+
Expression.new(
67+
:+,
68+
Variable.new("variable_a"),
69+
Variable.new("variable_b"),
70+
output: "variable_c" # defines where to store the result value
71+
)
72+
)
73+
#=> 3
74+
75+
environment.variables
76+
#=> { "variable_a" => 1, "variable_b" => 2, "variable_c" => 3 }
77+
```
78+
79+
When evaluating multiple objects at a time, the value of the _last_ object will be returned.
80+
81+
```ruby
82+
environment = Environment.new
83+
environment.evaluate(
84+
Scalar.new(1),
85+
Expression.new(:+, Scalar.new(1), Scalar.new(2))
86+
)
87+
#=> 3
88+
```
89+
90+
### Serialization (to JSON)
91+
92+
All models support serialization via:
93+
- `as_json`: builds a serializable hash representation of the object
94+
- `to_json`: builds a JSON string representing the object
95+
96+
### Building (from JSON)
97+
98+
<!-- TODO -->
99+
100+
### Beyond math
101+
102+
<!-- TODO -->
103+
104+
## Development
105+
106+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
107+
108+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
109+
110+
## Contributing
111+
112+
Bug reports and pull requests are welcome on GitHub at https://github.com/omkarmoghe/expressive.
113+
114+
## License
115+
116+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

Rakefile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
3+
require "bundler/gem_tasks"
4+
require "minitest/test_task"
5+
6+
Minitest::TestTask.create
7+
8+
require "rubocop/rake_task"
9+
10+
RuboCop::RakeTask.new
11+
12+
task default: %i[test rubocop]

bin/console

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
require "bundler/setup"
5+
require "expressive"
6+
7+
# You can add fixtures and/or initialization code here to make experimenting
8+
# with your gem easier. You can also use a different console, if you like.
9+
10+
require "irb"
11+
IRB.start(__FILE__)

bin/setup

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
IFS=$'\n\t'
4+
set -vx
5+
6+
bundle install
7+
8+
# Do any other automated setup that you need to do here

0 commit comments

Comments
 (0)