Can I reject objects which do not meet my criteria as they are entered into an array?
I k开发者_Go百科now there are a number of ways to create new elements in an existing ruby array.
e.g.
myArray = []
myArray + other_array
myArray << obj
myArray[index] = obj
I'm also pretty sure I could use .collect
, .map
, .concat
, .fill
, .replace
, .insert
, .join
, .pack
and .push
as well to add to or otherwise modify the contents of myArray
.
However, I want to ensure that myArray
only ever includes valid HTTP/HTTPS URLs.
Can anyone explain how I can enforce that kind of behaviour?
I would create a module that allows you to specify an acceptance block for an array, and then override all the methods you mention (and more, like concat
) to pre-filter the argument before calling super
. For example:
module LimitedAcceptance
def only_allow(&block)
@only_allow = block
end
def <<( other )
super if @only_allow[ other ]
end
def +( other_array )
super( other_array.select(&@only_allow) )
end
end
require 'uri'
my_array = []
my_array.extend LimitedAcceptance
my_array.only_allow do |item|
uri = item.is_a?(String) && URI.parse(item) rescue nil
uri.class <= URI::HTTP
end
my_array << "http://phrogz.net/"
my_array << "ftp://no.way"
my_array += %w[ ssh://bar http://ruby-lang.org http:// ]
puts my_array
#=> http://phrogz.net/
#=> http://ruby-lang.org
Create a class to encapsulate behavior you want. Then you can create your <<
method doing the verifications you want.
Put all logic that handle this data in methods in this domain class. Probably you will discover code floating around the use of this data to move to the new class.
My 2 cents.
Use this to insert. (untested).
def insert_to_array(first_array, second_array)
second_array.each do |i| {
if URI.parse(i).class == URI::HTTP
first_array.insert(i)
end
}
first_array
end
精彩评论