Emily
Emily

Reputation: 29

Using .match() inside of a block

I want to read a file and create an array of twitter handles. The file is a random collection of trending tweets, a snippet would be:

@David_Cameron @britishchambers #BCCConf Mention of pay rises in the NHS. But what about all the redundancies to enable these pay rises?

in which case the code should return

["@David_Cameron", "@britishchambers"]

Placing /@\w+/.match(word)[0] works in irb, but as soon as I put it in a block with each or map:

def read_file(file_path)
  text = File.open(file_path, 'r'){ |f| f.read}.split(" ")
  text.each{|word| /@\w+/.match(word)[0] }
end

then I receive the error:

NoMethodError: undefined method `[]' for nil:NilClass

What am I doing wrong? Also, if I can do this inside the file.open block, that would be preferable.

Upvotes: 0

Views: 57

Answers (2)

sawa
sawa

Reputation: 168071

What am I doing wrong?

By placing [] after /@\w+/.match(word), you are assuming that word always matches /@\w+/, thereby returning a MatchData object, which is not true. For example #BCCConf, does not match /@\w+/, in which case /@\w+/.match(word) is nil. [] is not defined on nil.

Upvotes: 1

Simone Carletti
Simone Carletti

Reputation: 176352

def read_file(file_path)
  text = File.read(file_path)
  text.scan(/@\w+/).flatten
end

Read the file, then use #scan to extract all the occurrences.

Upvotes: 0

Related Questions