{"id":15293334,"url":"https://github.com/jonathanhefner/dumb_delimited","last_synced_at":"2025-11-11T20:25:17.915Z","repository":{"id":59153079,"uuid":"96038650","full_name":"jonathanhefner/dumb_delimited","owner":"jonathanhefner","description":"Library for unsophisticated delimited flat file IO","archived":false,"fork":false,"pushed_at":"2023-03-18T21:01:52.000Z","size":48,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-27T04:22:36.524Z","etag":null,"topics":["csv","flat-file","psv","ruby","tsv"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonathanhefner.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-07-02T17:26:34.000Z","updated_at":"2022-01-24T19:14:13.000Z","dependencies_parsed_at":"2024-12-04T17:35:24.615Z","dependency_job_id":"4e0c1e50-1533-4d08-b18c-812bee65b84c","html_url":"https://github.com/jonathanhefner/dumb_delimited","commit_stats":{"total_commits":65,"total_committers":2,"mean_commits":32.5,"dds":0.3076923076923077,"last_synced_commit":"15acbd95ae80fd5876ab361a3f07efbbd6920af3"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanhefner%2Fdumb_delimited","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanhefner%2Fdumb_delimited/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanhefner%2Fdumb_delimited/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonathanhefner%2Fdumb_delimited/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonathanhefner","download_url":"https://codeload.github.com/jonathanhefner/dumb_delimited/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248718101,"owners_count":21150507,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csv","flat-file","psv","ruby","tsv"],"created_at":"2024-09-30T16:46:21.055Z","updated_at":"2025-11-11T20:25:17.871Z","avatar_url":"https://github.com/jonathanhefner.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dumb_delimited\n\nA library for unsophisticated delimited flat file IO.  *dumb_delimited*\nmixes models and persistence in that \"probably wrong but feels so right\"\nkind of way.\n\n\n## Usage Example\n\nLet's say we have a products file \"products.csv\", and a customers\nfile \"customers.psv\".\n\n\"products.csv\" is a comma-delimited flat file and has four columns: SKU,\nProduct Name, Base Price, and Sale Price.  An example row from\n\"products.csv\" might be:\n\n```\nAB81H0F,Widget Alpha,899.99,499.99\n```\n\n\"customers.psv\" is a pipe-delimited flat file and has three columns:\nCustomer Name, Email, and Address.  An example row from \"customers.psv\"\nmight be:\n\n```\nBob Bobbington|best_bob@bobbers.bob|808 Bounce Lane, Austin, TX 78703\n```\n\nTo interact with these files, we create model classes via the\n`DumbDelimited::[]` method.  Note that a created class can either be\nused as a superclass or simply assigned to a constant.\n\n```ruby\nclass Product \u003c DumbDelimited[:sku, :name, :base_price, :sale_price]\n  def on_sale?\n    sale_price.to_f \u003c base_price.to_f\n  end\nend\n\nCustomer = DumbDelimited[:name, :email, :address]\nCustomer.delimiter = \"|\"\n```\n\nBecause \"customers.psv\" is pipe-delimited, we also set the delimiter\nfor the Customer class.  By default, a model class uses a comma (`\",\"`)\nas its delimiter.  Whenever a delimiter is set, it applies to all future\nIO operations for that model class.\n\nConvenience shortcuts that create a model class and set its delimiter\nare also provided for a few common delimiters.  Notably,\n`DumbDelimited::psv` for a model class with a pipe (`\"|\"`) delimiter.\nThus, the `Customer` class could alternatively be written as:\n\n```ruby\nCustomer = DumbDelimited.psv(:name, :email, :address)\n```\n\nUsing our model classes, we can read each flat file, and recieve an\narray of model objects:\n\n```ruby\nproducts = Product.read(\"products.csv\")\ncustomers = Customer.read(\"customers.psv\")\n```\n\nHowever, this will load the entire contents of each file into memory.\nLet's say our customers file is very large, and we would prefer to\niterate over it one row at a time rather than load it all into memory at\nonce.  To do so, we can use the `read_each` method.  Below is a complete\nexample in which we load our product data, create a listing of products\non sale, and iterate over our customers, notifying each customer of the\nsale products:\n\n```ruby\nproducts = Product.read(\"products.csv\")\n\nlisting = products.select(\u0026:on_sale?).map do |product|\n  \"* #{product.name} (#{product.sale_price})\"\nend.join(\"\\n\")\n\nCustomer.read_each(\"customers.psv\") do |customer|\n  message = \u003c\u003c~MESSAGE\n    Hi #{customer.name}!\n\n    The following products are on sale:\n\n    #{listing}\n  MESSAGE\n\n  notify(customer.email, message)\nend\n```\n\nLet's say the sale is now over, and we want to change our sale prices\nback to our base prices.  We can load our product data, modify it\ndirectly, and finally persist it back with the `write` method:\n\n```ruby\nproducts = Product.read(\"products.csv\")\n\nproducts.each do |product|\n  product.sale_price = product.base_price\nend\n\nProduct.write(\"products.csv\", products)\n```\n\nFor a more detailed explanation of the *dumb_delimited* API, browse the\n[API documentation](https://www.rubydoc.info/gems/dumb_delimited/).\n\n\n## Installation\n\nInstall the [`dumb_delimited` gem](https://rubygems.org/gems/dumb_delimited).\n\n\n## Contributing\n\nRun `rake test` to run the tests.\n\n\n## License\n\n[MIT License](LICENSE.txt)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonathanhefner%2Fdumb_delimited","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonathanhefner%2Fdumb_delimited","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonathanhefner%2Fdumb_delimited/lists"}