2

I'm attempting to write a rudimentary MARC validator in ruby based on a short list of required and optional but desirable fields, partly as an exercise to write something in ruby, which I'm not terribly familiar with.

I've come up with what looks like valid ruby code to store my "optional" fields (and the script executes when this is enabled code):

Optional = ['006', '007', '010', '020', '022', {'040' => ['c']}, '041', ['050',  '060',  '082',  '086',  /09\d/], {/1\d\d/ => ['a']}, {'240' => ['a']}, '250', {'260' => ['a',  'b',  'c']}, {'300' => ['a']}, '490', /7[0-5]\d/, '830']

Based on my limited reading, this is technically feasible...but I'm not sure where to go from here. I'd like to iterate over the various fields in the record and if a field (or subfield if noted) is missing, write a warning to the screen:

sysnum = record['001']
record.fields.each do |field|
  Optional.each do |optfield|
    if field.tag =~ optfield
      break
    else
      puts "#{sysnum} is missing #{field.tag}"
    end
  end
end

However, that won't work for all of my cases, since not all of the optfield values will be a string. Should I be using an if block to test for hashes? What about the regex values? Will =~ test true for when the right side isn't a regex (string =~ otherstring instead of string =~ regex)?

Am I barking up the wrong tree altogether here?

ND Geek
  • 398
  • 6
  • 21
  • I think you also need to invert your logic. Iterate over the optional fields and check if each one is in the record. – Max May 06 '15 at 22:20
  • @Max, You're correct. Thanks for the catch! I probably wouldn't have noticed the logic error until I had more specific use cases to test with and found I wasn't getting errors I expected to see. – ND Geek May 07 '15 at 14:26

1 Answers1

1

You probably want to use ===, which you can read as "kinda equals". It works for both strings and regexps as you would expect:

'100' === '100'
# true
/1\d\d/ === '100'
# true

For your arrays, you can use Regexp.union which turns an array of strings into a regexp that matches any of those strings.

Max
  • 21,123
  • 5
  • 49
  • 71
  • It took a little bit of experimentation and reading, but between Regexp.union and the triple-equals, I was able to get my code working. One thing to note that gave me trouble is that the left side determines how `===` functions. Without knowing that, it can be a bit messy. – ND Geek May 12 '15 at 15:21
  • It's important to remember that `===` is a method, so it makes sense that the left side determines the behavior. The same goes for `==`, in fact. – Max May 12 '15 at 15:39
  • Yeah, not being familiar with Ruby, that was new to me. Now that I understand it, though, it's very useful. – ND Geek May 12 '15 at 15:41