364d0e86994a268906392f6b6146af38

Welcome to the 4th edition of Rubyize this! (http://www.rubyfleebie.com/rubyize-this-4th-edition) I have an array of insects and I want to be able to display the name, the iq and the annoyance factor of every members of a certain type. This "solution" works but has a ruby rating of 0.5/5. Moreover, it only works for butterflies... which feels rather incomplete and limiting. Remove stuff, add stuff and move stuff around. This dumb code must get smart and pretty!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class Bug
	attr_accessor :type
	attr_accessor :name
	attr_accessor :iq
	attr_accessor :annoyance_factor	
	
	def initialize(name,type,iq,annoyance_factor)
		if !type
			@type="spider"
		else
			@type=type
		end
		
		if !name
			@name="unnamed"
		else
			@name=name
		end		
		
		if !iq
			@iq = 8
		else
			@iq = iq
		end
		
		if !annoyance_factor
			@annoyance_factor = 4
		else
			@annoyance_factor = annoyance_factor
		end	
	end	
end

def keep_butterflies(bugs)
	butterflies = Array.new
	bugs.each do |bug|
		if bug.type == "butterfly"
			butterflies.push(bug)
		end
	end	
	return butterflies
end

#create some bugs!
bugs = Array.new
bugs.push(Bug.new("ron","spider","4","2"))
bugs.push(Bug.new("don","spider","2","3"))
bugs.push(Bug.new("jake","ant","9","4"))
bugs.push(Bug.new("chris","ladybug","2","4"))
bugs.push(Bug.new("fred","cockchaffer","0","5"))
bugs.push(Bug.new("greg","butterfly","2","0"))
bugs.push(Bug.new("jason","butterfly","0","2"))

butterflies=keep_butterflies(bugs)

butterflies.each do |butterfly|
	puts "I am a butterfly and my name is #{butterfly.name}. I have an IQ of #{butterfly.iq} and an annoyance factor of #{butterfly.annoyance_factor}"
end

Refactorings

No refactoring yet !

84540052d294a5a94bf3246b26747120

Julio

October 23, 2007, October 23, 2007 13:30, permalink

2 ratings. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Bug
  attr_accessor :type
  attr_accessor :name
  attr_accessor :iq
  attr_accessor :annoyance_factor	
	
  def initialize(name="unnamed",type="spider",iq=8,annoyance_factor=4)
    @annoyance_factor = annoyance_factor
    @type=type
    @name=name
    @iq = iq
  end

  def keep_butterflies(bugs)
    bugs.reject {|bug| bug.type != "butterfly" }
  end

  def create_bugs
    bugs = []
    bugs << Bug.new("ron","spider","4","2")
    bugs << Bug.new("don","spider","2","3")
    bugs << Bug.new("jake","ant","9","4")
    bugs << Bug.new("chris","ladybug","2","4")
    bugs << Bug.new("fred","cockchaffer","0","5")
    bugs << Bug.new("greg","butterfly","2","0")
    bugs << Bug.new("jason","butterfly","0","2")
    bugs
  end

  def print_butterflies
    keep_butterflies(create_bugs).each do |butterfly|
      puts "I am a butterfly and my name is #{butterfly.name}. I have an IQ of #{butterfly.iq} and an annoyance factor of #{butterfly.annoyance_factor}"
    end
  end

  print_butterflies

end
Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

October 23, 2007, October 23, 2007 13:50, permalink

3 ratings. Login to rate!

Here's my take. Bug as no logic in it so we can use the Struct class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Bug < Struct.new(:name, :type, :iq, :annoyance_factor); end

#create some bugs!
bugs = [
  Bug.new("ron","spider","4","2"),
  Bug.new("don","spider","2","3"),
  Bug.new("jake","ant","9","4"),
  Bug.new("chris","ladybug","2","4"),
  Bug.new("fred","cockchaffer","0","5"),
  Bug.new("greg","butterfly","2","0"),
  Bug.new("jason","butterfly","0","2")
]

butterflies = bugs.select { |b| b.type == 'butterfly' }

butterflies.each do |butterfly|
	puts "I am a butterfly and my name is #{butterfly.name}. I have an IQ of #{butterfly.iq} and an annoyance factor of #{butterfly.annoyance_factor}"
end
D86c9b2640edf72f4f002fd066a7b1f2

jswanner

October 23, 2007, October 23, 2007 14:27, permalink

1 rating. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Bug
  attr_accessor :type, :name, :iq, :annoyance_factor

  def initialize(name="unnamed", type="spider", iq=8, annoyance_factor=4)
    @type = type
    @name = name
    @iq = iq
    @annoyance_factor = annoyance_factor
  end

  #works with keep_type or keep_types, things like keep_butterflies does not work
  def Bug.method_missing(name, args)
    name = name.to_s
    if (name =~ /^keep_([a-z]+?)s?$/i)
      bugs = args.select{ |bug| bug.type == $1 }
    end
  end
end

bugs = [
  Bug.new("ron","spider","4","2"),
  Bug.new("don","spider","2","3"),
  Bug.new("jake","ant","9","4"),
  Bug.new("chris","ladybug","2","4"),
  Bug.new("fred","cockchaffer","0","5"),
  Bug.new("greg","butterfly","2","0"),
  Bug.new("jason","butterfly","0","2")
]

butterflies = Bug.keep_butterfly(bugs)

butterflies.each do |b|
  puts "I am #{b.name}, a beautiful #{b.type}.  I have an IQ of #{b.iq} and an annoyance factor of #{b.annoyance_factor}"
end
364d0e86994a268906392f6b6146af38

FrankLamontagne

October 23, 2007, October 23, 2007 14:28, permalink

No rating. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class Bug
  attr_accessor :name,:type,:iq,:annoyance_factor
  def initialize(name="unname",type=:spider,iq=8,annoyance_factor=4)
	@name=name
	@type=type
	@iq=iq
	@annoyance_factor=annoyance_factor
  end  
end

class Bugs < Array
  def keep(type)
    self.reject! { |b| b.type != type }
  end
  
  def talk!
    self.each do |bug|
      puts "I am a #{bug.type.to_s} and my name is #{bug.name}. I have an IQ of #{bug.iq} and an annoyance factor of #{bug.annoyance_factor}"
    end
  end
end

bugs = Bugs.new([
  Bug.new("ron",:spider,4,2),
  Bug.new("don",:spider,2,3),
  Bug.new("jake",:ant,9,4),
  Bug.new("chris",:ladybug,2,4),
  Bug.new("fred",:cockchaffer,0,5),
  Bug.new("greg",:butterfly,2,0),
  Bug.new("jason",:butterfly,0,2)
])

bugs.keep(:butterfly)
bugs.talk!
5978e2ed3a31f1bd2361dbb919d92012

Mike Woodhouse

October 23, 2007, October 23, 2007 15:07, permalink

No rating. Login to rate!

I'm wondering if I may have strayed away from refactoring and into code golf here...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Bug
  attr_accessor(:bug_type, :name, :iq, :annoyance_factor)
  def initialize(name = "unnamed", bug_type = "spider", iq = 8, annoyance_factor = 4)
    @annoyance_factor, @bug_type, @name, @iq = annoyance_factor, bug_type, name, iq
  end
  def describe
    puts "I am a #{@bug_type} and my name is #{@name}. I have an IQ of #{@iq} and an annoyance factor of #{@annoyance_factor}"
  end
end

class Bugs < Array
  def describe_all(filter_type)
    each do |bug| 
      bug.describe if bug.bug_type == filter_type
    end
  end
end

BUGDEFS = [["ron","spider","4","2"],["don","spider","2","3"],
          ["jake","ant","9","4"],["chris","ladybug","2","4"],
          ["fred","cockchaffer","0","5"],["greg","butterfly","2","0"],
          ["jason","butterfly","0","2"]]
bugs = Bugs.new
BUGDEFS.each { |bug_def| bugs << Bug.new(*bug_def) }

bugs.describe_all "butterfly"
Avatar

Panya

October 23, 2007, October 23, 2007 16:29, permalink

No rating. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Bug
  attr_accessor :type, :name, :iq, :annoyance_factor
	
  def initialize(name='unnamed',type='spider',iq=8,annoyance_factor=4)
    @name, @type, @iq, @annoyance_factor = name, type, iq, annoyance_factor
  end

  def to_s
   "I am a #@type and my name is #@name. I have an IQ of #@iq and an annoyance factor of #@annoyance_factor" 	
  end
end

class Bugs < Array
  def keep(type)
    self.select{|bug| bug.type == type}
  end
end

#create some bugs!
bugs = Bugs.new([
  Bug.new("ron","spider","4","2"),
  Bug.new("don","spider","2","3"),
  Bug.new("jake","ant","9","4"),
  Bug.new("chris","ladybug","2","4"),
  Bug.new("fred","cockchaffer","0","5"),
  Bug.new("greg","butterfly","2","0"),
  Bug.new("jason","butterfly","0","2")
])
bugs.keep("butterfly").each{|butterfly| puts butterfly}
F9ac05fdd57915983ccea58699e1f942

Mark Van Holstyn

October 23, 2007, October 23, 2007 17:09, permalink

2 ratings. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
require 'rubygems'
require 'active_support'

class Bug < Struct.new(:name, :type, :iq, :annoyance_factor)
  def to_s
    "I am a #{type} and my name is #{name}. I have an IQ of #{iq} and an annoyance factor of #{annoyance_factor}"
  end
end

class Bugs < Array
  def method_missing(method_name, *args, &block)
    Bugs.new(select { |bug| bug.type.to_s == method_name.to_s.singularize })
  end
end

bugs = Bugs.new [
  Bug.new("ron",    :spider,       4,  2),
  Bug.new("don",    :spider,       2,  3),
  Bug.new("jake",   :ant,          9,  4),
  Bug.new("chris",  :ladybug,      2,  4),
  Bug.new("fred",   :cockchaffer,  0,  5),
  Bug.new("greg",   :butterfly,    2,  0),
  Bug.new("jason",  :butterfly,    0,  2)
]

puts *bugs.spiders
45a4605513f333896475b723378712ee

Mike Abney

October 23, 2007, October 23, 2007 23:22, permalink

1 rating. Login to rate!

Nothing too special here, just felt like posting something. I like others' use of "method_missing", but it just seemed a bit more work than was necessary.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Bug
	attr_accessor :type, :name, :iq, :annoyance_factor
	
	def initialize(name="unnamed", type="spider", iq=8, annoyance_factor=4)
			@type=type
			@name=name
			@iq = iq
			@annoyance_factor = annoyance_factor
	end
	
	def introduction
  	"I am a #{@type} and my name is #{@name}. I have an IQ of #{@iq} and an annoyance factor of #{@annoyance_factor}."
  end
end

class Bugs < Array
  def keep(type)
    Bugs.new(select { |bug| bug.type == type })
  end
  
  def keep!(type)
    select! { |bug| bug.type == type }
  end
  
  def introductions
    collect { |bug| bug.introduction}
  end
end

#create some bugs!
bugs = Bugs.new [
  Bug.new("ron","spider","4","2"),
  Bug.new("don","spider","2","3"),
  Bug.new("jake","ant","9","4"),
  Bug.new("chris","ladybug","2","4"),
  Bug.new("fred","cockchaffer","0","5"),
  Bug.new("greg","butterfly","2","0"),
  Bug.new("jason","butterfly","0","2")
]

puts bugs.keep("butterfly").introductions
51a9109ac81a962fe2a9641821c9e2b7

Shalev

October 24, 2007, October 24, 2007 00:26, permalink

2 ratings. Login to rate!

Shortest complete solution. The struct solutions are good, but they don't allow for default values.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Bug
  attr_accessor :name, :type, :iq, :annoyance_factor

  def initialize(name='unnamed', type='spider', iq=8, annoyance_factor=4)
    @name, @type, @iq, @annoyance_factor = name, type, iq, annoyance_factor
  end

  def to_s
    "I am a #{type} and my name is #{name}. I have an IQ of #{iq} and an annoyance factor of #{annoyance_factor}"
  end
end

puts [ ["ron","spider","4","2"],["don","spider","2","3"],
          ["jake","ant","9","4"],["chris","ladybug","2","4"],
          ["fred","cockchaffer","0","5"],["greg","butterfly","2","0"],
          ["jason","butterfly","0","2"] ].map {|args| Bug.new(*args)}.select {|bug| bug.type == 'spider'}
7c45f63f61e478233f0c2ad3006b178c

michiel

October 24, 2007, October 24, 2007 11:15, permalink

No rating. Login to rate!

Building on Mark Van Holstyn's solution, keeping the 'keep_spiders' syntax and cleaner syntax for entering bugs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
require 'rubygems'
require 'active_support'

MSG = "I am a %s and my name is %s. I have an IQ of %s and an annoyance factor of %s"

class Bug < Struct.new(:type, :desc)
  alias to_s desc
end

class Bugs < Array
  def method_missing(name, *_)
    return super unless name.to_s =~ /^keep_/
    Bugs.new(select { |bug| bug.type.to_s == name.to_s[5..-1].singularize })
  end
end

def make_bugs(bugs = Bugs.new)
  yield lambda {|*a| bugs << Bug.new(a[1], sprintf(MSG, *a)) }
end

bugs = make_bugs do |bug|
  bug["ron",    :spider,       4,  2]
  bug["don",    :spider,       2,  3]
  bug["jake",   :ant,          9,  4]
  bug["chris",  :ladybug,      2,  4]
  bug["fred",   :cockchaffer,  0,  5]
  bug["greg",   :butterfly,    2,  0]
  bug["jason",  :butterfly,    0,  2]
end

puts bugs.keep_butterflies
0867ef12857eb0b0b43ea207df5884e4

Calvin Yu

October 26, 2007, October 26, 2007 00:17, permalink

1 rating. Login to rate!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Bug
  attr_accessor :type, :name, :iq, :annoyance_factor	
	
  def initialize(name='unnamed',type='spider',iq=8,annoyance_factor=4)
    @name, @type, @iq, @annoyance_factor = name, type, iq, annoyance_factor
  end	

  def to_s
    "I am a #{type} and my name is #{name}. I have an IQ of #{iq} and an annoyance factor of #{annoyance_factor}"
  end

  def method_missing(method_name, *args, &block)
     method_name.to_s[-1] == ?? ? (@type == method_name.to_s[0..-2]) : super
  end
end

#create some bugs!
puts [
  %w( ron   spider      4 2 ),
  %w( don   spider      2 3 ),
  %w( jake  ant         9 4 ),
  %w( chris ladybug     2 4 ),
  %w( fred  cockchaffer 0 5 ),
  %w( greg  butterfly   2 0 ),
  %w( jason butterfly   0 2 )].map {|args| Bug.new(*args)}.select {|bug| bug.butterfly?}
Avatar

Chris T

October 26, 2007, October 26, 2007 17:40, permalink

No rating. Login to rate!

Similar to above but the method missing on the Bug class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Bug
  attr_accessor :type, :name, :iq, :annoyance_factor	
  
  def initialize(name = "unnamed",type = "spider",
      iq = 8, annoyance_factor = 4)
    @type= type 
    @name=name
    @iq = iq
    @annoyance_factor = annoyance_factor 
  end
  
  def method_missing(method_name, *args)
    #check for <type>?
    if method_name.to_string =~/\?\z/ 
      $` == @type
    else
      super.method_missing(method_name, *args)
    end
  end
end


#create some bugs!
bugs = [
  Bug.new("ron","spider","4","2"),
  Bug.new("don","spider","2","3"),
  Bug.new("jake","ant","9","4"),
  Bug.new("chris","ladybug","2","4"),
  Bug.new("fred","cockchaffer","0","5"),
  Bug.new("greg","butterfly","2","0"),
  Bug.new("jason","butterfly","0","2"), 
  ]

bugs.each do |bug|
  if bug.butterfly? then 
    puts "I am a butterfly and my name is #{bug.name}. I have an IQ of #{bug.iq} and an annoyance factor of #{bug.annoyance_factor}"
  end
end
1a18d240b68c5cad64a205a8c17442a7

Justin Jones

October 29, 2007, October 29, 2007 07:08, permalink

No rating. Login to rate!

Some pretty crazy method_missing stuff... too "clever", imo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
require 'rubygems'
require 'active_support'

class Bug
  attr_accessor :name, :type, :iq, :annoyance_factor

  def initialize(type=:spider, name='unnamed', iq=8, annoyance_factor=4)
    @name, @type, @iq, @annoyance_factor = name, type, iq, annoyance_factor
  end

  def to_s
    "I am a #{type} and my name is #{name}. I have an IQ of #{iq} and an annoyance factor of #{annoyance_factor}"
  end
end

class Bugs < Array
  class << self
    def swarm(bugs = Bugs.new, &block)
      yield(bugs)
    end

    def method_missing(method_name, *args, &block)
      return super unless method_name.to_s =~ /_swarm$/
      swarm(*args, &block).send("keep_#{method_name.to_s[0..-7]}")
    end
  end

  def method_missing(method_name, *args)
    if method_name.to_s =~ /^keep_/
      select { |bug| bug.type.to_s == method_name.to_s[5..-1].singularize }
    else
      self << Bug.new(method_name, *args)
    end
  end
end

all_bugs = Bugs.swarm do |bug|
  bug.spider('Ron', 4, 2)
  bug.spider('Don', 2, 3)
  bug.ant('Jake', 9, 4)
  bug.ladybug('Chris', 2, 4)
  bug.cockchaffer('Fred', 0, 5)
  bug.butterfly('Greg', 2, 0)
  bug.butterfly('Jason', 0, 2)
end

puts "Spiders"
puts all_bugs.keep_spiders

butterflies = Bugs.butterfly_swarm do |bug|
  bug.spider('Ron', 4, 2)
  bug.spider('Don', 2, 3)
  bug.ant('Jake', 9, 4)
  bug.ladybug('Chris', 2, 4)
  bug.cockchaffer('Fred', 0, 5)
  bug.butterfly('Greg', 2, 0)
  bug.butterfly('Jason', 0, 2)
end

puts "\nButterflies"
puts butterflies

ants = Bugs.ant_swarm(all_bugs) do |bug|
  bug.ant('Ants', 10, 3)
  bug.splat('Dead Bug', 0, 0)
end

puts "\nAnts"
puts ants
Dd9b278833b2db936814ac37a546a55f

fifoo

January 4, 2008, January 04, 2008 21:44, permalink

No rating. Login to rate!

Nothing too clever I'm afraid.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class Bug

  attr_reader :name, :type, :iq, :annoyance_factor

  def initialize(name = "unnamed", type = :spider, iq = 8, annoyance_factor = 4)
    @name, @type, @iq, @annoyance_factor = name, type, iq, annoyance_factor
  end

  def to_s
    "I am a #{type} and my name is #{name}. I have an IQ of #{iq} and an annoyance factor of #{annoyance_factor}\n"
  end

end

class BugCollection < Array

  def add(*args)
    self << Bug.new(*args)
  end

  def keep(type)
    select { |b| b.type == type }
  end

  def keep!(type)
    delete_if { |b| b.type != type }
  end

end

#create some bugs!
bugs = BugCollection.new

[ ["ron",   :spider,      4, 2],
  ["don",   :spider,      2, 3],
  ["jake",  :ant,         9, 4],
  ["chris", :ladybug,     2, 4],
  ["fred",  :cockchaffer, 0, 5],
  ["greg",  :butterfly,   2, 0],
  ["jason", :butterfly,   0, 2] ].each { |bug_details| bugs.add(*bug_details) }


puts bugs

puts "-- spiders:"
puts bugs.keep(:spider)

puts "-- butterflies:"
bugs.keep!(:butterfly)
puts bugs
8802b1fa1b53e2197beea9454244f847

Sean Cribbs

January 26, 2008, January 26, 2008 18:01, permalink

No rating. Login to rate!

I was surprised the other solutions don't have the class itself keeping track of instances.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Bug
  attr_accessor :type, :name, :iq, :annoyance_factor 
  @@bugs = []

  def initialize(name='unnamed',type='spider',iq=8,annoyance_factor=4)
    @type, @name, @iq, @annoyance_factor = type, name, iq, annoyance_factor
    @@bugs << self
  end

  def self.[](type)
    @@bugs.select { |bug| bug.type == type }
  end
  
  def inspect
    "I am a #{type} and my name is #{name}. I have an IQ of #{iq} and an annoyance factor of #{annoyance_factor}"
  end

  alias :to_s :inspect
end

#create some bugs!
Bug.new("ron",    "spider",       4, 2)
Bug.new("don",    "spider",       2, 3)
Bug.new("jake",   "ant",          9, 4)
Bug.new("chris",  "ladybug",      2, 4)
Bug.new("fred",   "cockchaffer",  0, 5)
Bug.new("greg",   "butterfly",    2, 0)
Bug.new("jason",  "butterfly",    0, 2)

Bug["butterfly"].each do |butterfly|
  puts butterfly
end

Your refactoring





Format Copy from initial code

or Cancel