3

So, I'm trying to build a quick console program for my development needs, akin to rails console (I'm using Sinatra + DataMapper + pry).

I run it and launch cat = Category.new(name: 'TestCat', type: :referential). It gives me the following error:

Error: Cannot open "/home/art-solopov/Projects/by-language/Ruby/billy-bones/=" for reading.

What could be the cause of the problem?

console:

#!/usr/bin/env ruby
$LOAD_PATH << 'lib'

require 'pry'
require 'config'

binding.pry

lib/config.rb:

# Configuration files and app-wide requires go here

require 'sinatra'
require 'data_mapper'
require 'model/bill'
require 'model/category'
configure :production do
  DataMapper::Logger.new('db-log', :debug)
  DataMapper.setup(:default,
    'postgres://billy-bones:billy@localhost/billy-bones')
  DataMapper.finalize
end

configure :development do
  DataMapper::Logger.new($stderr, :debug)
  DataMapper.setup(:default,
    'postgres://billy-bones:billy@localhost/billy-bones-dev')
  DataMapper.finalize
  DataMapper.auto_upgrade!
end

configure :test do
  require 'dm_migrations'
  DataMapper::Logger.new($stderr, :debug)
  DataMapper.setup(:default,
    'postgres://billy-bones:billy@localhost/billy-bones-test')
  DataMapper.finalize
  DataMapper.auto_migrate!
end

lib/model/category.rb:

require 'data_mapper'

class Category
    include DataMapper::Resource

    property :id, Serial
    property :name, String
    property :type, Enum[:referential, :predefined, :computable]

    has n, :bills
    # has n, :tariffs TODO uncomment when tariff ready

    def create_bill(params)
      # A bill factory for current category type
      case type
      when :referential
        ReferentialBill.new params
      when :predefined
        PredefinedBill.new params
      when :computable
        ComputableBill.new params
      end
    end

end

If I substitute pry with irb in the console script, it goes fine.

Thank you very much!

P. S.

Okay, yesterday I tried this script again, and it worked perfectly. I didn't change anything. I'm not sure whether I should remove the question now or not.

P. P. S.

Or actually not... Today I've encountered it again. Still completely oblivious to what could cause it.

** SOLVED **

DAMN YOU PRY!

Okay, so here's the difference.

When I tested it the second time, I actually entered a = Category.new(name: 'TestCat', type: :referential) and it worked. Looks like pry just thinks cat is a Unix command, not a valid variable name.

art-solopov
  • 4,289
  • 3
  • 25
  • 44

1 Answers1

0

Not answer to the pry question I just generally hate case statements in ruby.

Why not change:

def create_bill(params)
  # A bill factory for current category type
  case type
  when :referential
    ReferentialBill.new params
  when :predefined
    PredefinedBill.new params
  when :computable
    ComputableBill.new params
  end
end

to:

def create_bill(params)
  # A bill factory for current category type
  self.send("new_#{type}_bill",params)
end
def new_referential_bill(params)
  ReferentialBill.new params
end
def new_predefined_bill(params)
  PredefinedBill.new params
end
def new_computable_bill(params)
  ComputableBill.new params
end

You could make this more dynamic but I think that would take away from readability in this case but if you'd like in rails this should do the trick

def create_bill(params)
  if [:referential, :predefined, :computable].include?(type)
    "#{type}_bill".classify.constantize.new(params)
  else
    #Some Kind of Handling for non Defined Bill Types
  end
end

Or this will work inside or outside rails

def create_bill(params)
  if [:referential, :predefined, :computable].include?(type)
    Object.const_get("#{type.to_s.capitalize}Bill").new(params)
  else
    #Some Kind of Handling for non Defined Bill Types
  end
end
engineersmnky
  • 25,495
  • 2
  • 36
  • 52