Search objects

D

Dark Ambient

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")
 
M

Morton Goldberg

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
 
D

Dark Ambient

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

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


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")
 
J

James Edward Gray II

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")

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 Gray II
 
A

ara.t.howard

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")

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, key
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
 
D

Dark Ambient

That's a lot of food :)

Stuart

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")

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, key
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,209
Messages
2,571,088
Members
47,687
Latest member
IngridXxj

Latest Threads

Top