# Search objects

**URL:** <https://www.ruby-forum.com/t/search-objects/64800>\
**Category:** Ruby\
**Created:** [August 15, 2006, 2:19pm UTC](https://www.ruby-forum.com/t/search-objects/64800 "2006-08-15T14:19:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [August 15, 2006, 2:19pm UTC](https://www.ruby-forum.com/t/search-objects/64800/1 "2006-08-15T14:19:08Z")

</div>

I can use some help here:

I’ve set up this class and objects and would like to “search” it  
similar to the way I would search a database. At this point I’m not  
concerned with adding regex for more liberal searches.  
Any suggestions ?

class Composer  
def initialize( lname, country )  
@lname = lname  
@country = country  
end  
attr\_accessor(:lname, :country)  
end

comp1 = Composer.new(“Beethoven”, “Germany”)  
comp2 = Composer.new(“DeFalla”, “Spain”)  
comp3 = Composer.new(“Debussy”, “France”)

---

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [August 15, 2006, 2:19pm UTC](https://www.ruby-forum.com/t/search-objects/64800/2 "2006-08-15T14:19:09Z")

</div>

I’m assuming that you are just implementing this for its educational  
value and not seriously considering implementing a data base with  
this approach. Ruby has built-in and third-party libraries to help  
you implement a data bases application.

I’ve modified your posting just enough to make a shallow scratch on  
the surface of what can be done to organize and search data. I hope  
it’s enough to help you along. Although you said you didn’t want to  
consider regular expressions yet, I use them because it makes life  
much simpler to use at least simple regexes.

#! /usr/bin/ruby -w

class Composer

```
@@composers = []

def Composer.find(attrib, regex)
   @@composers.select do |c|
      c.respond_to?(attrib) &&
      c.send(attrib) =~ regex
   end
end

def initialize( lname, country )
    @lname = lname
    @country = country
    @@composers << self
end

attr_accessor :lname, :country
alias :to_s :inspect

```

end

Composer.new(“Beethoven”, “Germany”)  
Composer.new(“DeFalla”, “Spain”)  
Composer.new(“Debussy”, “France”)  
Composer.new(“Bach”, “Germany”)  
Composer.new(“Rodrigo”, “Spain”)  
Composer.new(“Ravel”, “France”)

puts Composer.find(:country, /^Ger/)  
puts Composer.find(:lname, /^R/)

# =\>

# #\<Composer:0x24a18 @country=“Germany”, @lname=“Beethoven”\>

# #\<Composer:0x24964 @country=“Germany”, @lname=“Bach”\>

# #\<Composer:0x24928 @country=“Spain”, @lname=“Rodrigo”\>

# #\<Composer:0x248ec @country=“France”, @lname=“Ravel”\>

Regards, Morton

---

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [August 15, 2006, 2:19pm UTC](https://www.ruby-forum.com/t/search-objects/64800/3 "2006-08-15T14:19:10Z")

</div>

Well a few things. For some reason, in the past I’ve attempted to use  
‘find’ in Ruby and irb has sent back a nomethod error. So perhaps t  
was syntax errors (though I don’t believe it was) not sure. I’m about  
to run out so I’ll check it in a while.

And yes, this is for educational purposes though I think I may have  
not seen some options. Particularly the ability in Rails to play with  
models and controllers in the console. I know this is not the Rails  
list and I’ve gone ahead posted my errors while attempting to load the  
console using the NAME or DESCRIPTION option.

Stuart

---

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [August 15, 2006, 2:19pm UTC](https://www.ruby-forum.com/t/search-objects/64800/4 "2006-08-15T14:19:10Z")

</div>

On Aug 13, 2006, at 12:54 PM, Dark A. wrote:

> def initialize( lname, country )  
> @lname = lname  
> @country = country  
> end  
> attr\_accessor(:lname, :country)  
> end
> 
> comp1 = Composer.new(“Beethoven”, “Germany”)  
> comp2 = Composer.new(“DeFalla”, “Spain”)  
> comp3 = Composer.new(“Debussy”, “France”)

Well, if we had those composers in an Array, we could use normal  
iterators like:

composers.find { |c| c.country == “Germany” }

and:

composers.select { |c| c.lname =~ /^De/ }

Hope that gives you some fresh ideas.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [August 15, 2006, 2:19pm UTC](https://www.ruby-forum.com/t/search-objects/64800/5 "2006-08-15T14:19:11Z")

</div>

On Mon, 14 Aug 2006, Dark A. wrote:

> ```
> @country = country
> 
> ```
> 
> end  
> attr\_accessor(:lname, :country)  
> end
> 
> comp1 = Composer.new(“Beethoven”, “Germany”)  
> comp2 = Composer.new(“DeFalla”, “Spain”)  
> comp3 = Composer.new(“Debussy”, “France”)

harp:~ \> cat a.rb  
require ‘weakref’

class Composer  
(ATTRIBUTES = %w( lname country )).each{|a| attr\_accessor a}

INDEX = Hash.new{|h,k| h[k] = []}

def self.find arg  
pattern =  
case arg  
when Hash  
ATTRIBUTES.map{|a| arg[a] || arg[a.to\_s] ||  
arg[a.to\_s.intern]}  
when Array  
arg  
else  
raise ArgumentError  
end

```
 n = pattern.size

 keys = INDEX.keys.select do |key|
   match = []
   n.times do |i|
     pat, k = pattern[i], key[i]
     match <<
       if pat.nil?
         true
       elsif pat.respond_to? 'call'
         pat.call(k) ? true : false
       elsif pat.respond_to? '==='
         pat === k
       elsif pat.respond_to? '=='
         pat == k
       else
         false
       end
   end
   match.all?
 end

 INDEX.values_at(*keys).map{|list| list.map{|weakref| 

```

weakref. **getobj** }}.flatten  
end

def initialize \*argv  
ATTRIBUTES.each{|a| send “#{ a }=”, argv.shift}  
key = ATTRIBUTES.map{|a| send a}  
val = WeakRef.new self  
INDEX[key] \<\< val  
end

def to\_hash  
ATTRIBUTES.inject({}){|h,k| h.update k =\> send(k)}  
end

def inspect  
to\_hash.inspect  
end

def to\_s  
inspect  
end  
end

comp1 = Composer.new “Beethoven”, “Germany”  
comp2 = Composer.new “DeFalla”, “Spain”  
comp3 = Composer.new “Debussy”, “France”

found = Composer.find ‘lname’ =\> ‘Beethoven’  
p found

found = Composer.find ‘lname’ =\> %r/^bee|^defal/io  
p found

found = Composer.find :country =\> lambda{|c| c.upcase === ‘SPAIN’}  
p found

class CaseOf \< ::Array  
def ===(other) flatten.compact.map{|pat| pat === other}.any? end  
end  
def caseof(\*a, &b) CaseOf.new(\*a, &b) end

found = Composer.find :lname =\> %r/y$/, :country =\> caseof(%w[ Spain  
France ])  
p found

harp:~ \> ruby a.rb  
[{“country”=\>“Germany”, “lname”=\>“Beethoven”}]  
[{“country”=\>“Germany”, “lname”=\>“Beethoven”}, {“country”=\>“Spain”,  
“lname”=\>“DeFalla”}]  
[{“country”=\>“Spain”, “lname”=\>“DeFalla”}]  
[{“country”=\>“France”, “lname”=\>“Debussy”}]

food for thought.

-a

---

<div class="post-metadata">

**Author:** ![zanoni](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/z/e99b99/32.png) [@zanoni](https://www.ruby-forum.com/u/zanoni)\
**Post date:** [August 15, 2006, 2:19pm UTC](https://www.ruby-forum.com/t/search-objects/64800/6 "2006-08-15T14:19:16Z")

</div>

That’s a lot of food 🙂

Stuart
