diff --git a/week1/exercises/roster.txt b/week1/exercises/roster.txt index 21b0964..599e656 100644 --- a/week1/exercises/roster.txt +++ b/week1/exercises/roster.txt @@ -17,6 +17,6 @@ 15, Owen, owen.james.kelly@gmail.com, owenkelly, n/a, @owenkelly 16, Robert McCreary Mannino, rmccreary8@gmail.com, psytau, maalaoshi, rmccreary8@gmail.com 17, Rukia, rukk86@gmail.com, rukk86, no twitter, Rukia -18, +18, Sarah, sarahcwheeler@gmail.com, sarahwheeler, @SeeSarahCode, Sarah Wheeler 19, 20, Zack Walkingstick, zackwalkingstick@gmail.com, zackwalkingstick, no twitter, @zack diff --git a/week1/homework/questions.txt b/week1/homework/questions.txt index 2257bb9..4ecd469 100644 --- a/week1/homework/questions.txt +++ b/week1/homework/questions.txt @@ -1,15 +1,77 @@ +Sarah Wheeler +1/14/14 +Ruby 110 + +Week 1 Homework + Please read: Chapter 3 Classes, Objects, and Variables p.86-90 Strings (Strings section in Chapter 6 Standard Types) + + 1. What is an object? + An object is simply an instance of a class. Every object + has a unique object id (because it occupies a unique space + in the computer's memory), is associated with a class, and + can be instantiated through the .new method. Multiple + variables can point to the same object, however. + 2. What is a variable? + A variable is not an object, but actually holds a reference + to an object. Syntactically, variables should be all lowercase, + can start with or include underscores, and include (but not + begin with) numbers. Depending on whether they are prefixed + by $, @, @@, or no symbol at all, the scope of the variable + changes. For example, you can't access an object's instance + variables until you have written an accessor method in the + class definition, because its scope is restricted to where + it was first created. + 3. What is the difference between an object and a class? + Classes are not objects themselves, but they do act as the + blueprints for objects. They allow you to dictate what actions + can be performed with, to, and through objects by giving you + the power to define the methods that will be available to them. + Classes are used to instantiate individual objects that are a + referenced through the use of variables. + 4. What is a String? + Strings are sequences of characters (either binary or printable) + that belong to the String class. Strings are created with string + literals (example: string1 = "String!") and can appear between + either single or double quotes. + 5. What are three messages that I can send to a string object? Hint: think methods + .capitalize will tell a String object to make the first letter + of your string a capital letter. + + .split will divide a String object by the character you pass it + (for example, a comma, period, or vertical bar), and create an + Array out of the pieces. + + .length will tell you how many characters a String object contains. + + 6. What are two ways of defining a String literal? Bonus: What is the difference between them? + + Method 1: By using single quotes as your delimiters, like so: + + 'This is a string.' + + Method 2: By using %Q followed by any nonalphanumeric or nonmultibyte + character, which acts like a double quote like so: + + %Q{This is also a string.} + + The difference between single quotes and double quotes is that double + quotes support more escape sequences, as well as string interpolation + (inserting a variable into text through #{variable}). Since single + quotes perform fewer functions, they are also processed slightly faster + by the computer. + diff --git a/week1/homework/strings_and_rspec_spec.rb b/week1/homework/strings_and_rspec_spec.rb index ea79e4c..1e4f1a4 100644 --- a/week1/homework/strings_and_rspec_spec.rb +++ b/week1/homework/strings_and_rspec_spec.rb @@ -12,14 +12,18 @@ before(:all) do @my_string = "Renée is a fun teacher. Ruby is a really cool programming language" end - it "should be able to count the charaters" - it "should be able to split on the . charater" do - pending - result = #do something with @my_string here + it "should be able to count the characters" do + @my_string.should have(66).characters + end + it "should be able to split on the . character" do + #pending + result = @my_string.split(".") result.should have(2).items end it "should be able to give the encoding of the string" do - pending 'helpful hint: should eq (Encoding.find("UTF-8"))' + #pending 'helpful hint: should eq (Encoding.find("UTF-8"))' + @my_string.encoding.should eq Encoding.find("UTF-8") + end end end diff --git a/week2/homework/questions.txt b/week2/homework/questions.txt index 939e42d..0989bdd 100644 --- a/week2/homework/questions.txt +++ b/week2/homework/questions.txt @@ -1,13 +1,55 @@ +Sarah Wheeler +1/22/14 +Ruby 110 + +Week 2 Homework + Please Read The Chapters on: Containers, Blocks, and Iterators Sharing Functionality: Inheritance, Modules, and Mixins 1. What is the difference between a Hash and an Array? + An array is indexed with integers, while a hash + can use any object as its index. Unlike arrays, + hashes store two objects when they are populated-- + the key (i.e., the index) and its value. + 2. When would you use an Array over a Hash and vice versa? + You would want to use an array if you wanted to + store collections of objects that can be accessed + through an integer index. If you found yourself + writing a hash that used integers for its unique + keys, you might be better off using an array instead. + + You would want to use a hash when your collection requires + more flexibility with the types of objects it can use for + indexes (i.e., non-integers). If you wanted to associate a + relationship between two strings, for example, a hash would + probably be the most appropriate collection to use. Another + major advantage is that Ruby will remember the order of the + items added to your hash. + 3. What is a module? Enumerable is a built in Ruby module, what is it? + A module is "a way of grouping together methods, classes, + and constants" (Pickaxe, p. 73, 4th ed). Although it isn't + a class and can't have instances, you can use its Mixin + functionality to lend its methods to other classes. + + Enumerable is a module that was created to provide collections + (arrays and hashes) with methods that allow them to sort, + search, and iterator through their elements. + 4. Can you inherit more than one thing in Ruby? How could you get around this problem? + Ruby is a single-class inheritance language, but through the use + of modules and mixins, it is possible to mimic multiple + inheritance in a controlled environment. + 5. What is the difference between a Module and a Class? + + A module cannot have instances, which means that it is not meant + to help create objects like a class is--instead, it is meant to + provide a set of specialized methods to another class. \ No newline at end of file diff --git a/week2/homework/simon_says.rb b/week2/homework/simon_says.rb new file mode 100644 index 0000000..a1767c6 --- /dev/null +++ b/week2/homework/simon_says.rb @@ -0,0 +1,24 @@ +module SimonSays + + def echo(message) + p message + end + + def shout(message) + p message.upcase + end + + def repeat(message, n=2) + p ([message] * n).join(' ') + end + + def start_of_word(word, n) + p word[0, n] # I REALLY overthought this method the first 80 times I tried it + # ... but at least I won't forget it now! + end + + def first_word(message) + word_one = message.split(" ") + p word_one[0] + end +end \ No newline at end of file diff --git a/week3/homework/calculator.rb b/week3/homework/calculator.rb new file mode 100644 index 0000000..fada313 --- /dev/null +++ b/week3/homework/calculator.rb @@ -0,0 +1,21 @@ +class Calculator + + def sum num + num.inject(0) {|sum, current| sum + current } + end + + def multiply x, y=1 + n = [x, y].flatten(1) + n.inject(1) { |sum, current| sum * current } + end + + def pow n1, n2 + n1**n2 + end + + def fac i + return 1 if i == 0 + (1..i).inject(:*) + end + +end \ No newline at end of file diff --git a/week3/homework/monster_questions.rb b/week3/homework/monster_questions.rb new file mode 100644 index 0000000..e28a401 --- /dev/null +++ b/week3/homework/monster_questions.rb @@ -0,0 +1,35 @@ +# Sarah Wheeler +# 1/28/14 +# Ruby 110 + +# Monster Questions + +# 1. How many monsters are nocturnal? + + $monsters.count { |m| m[:nocturnal] } + + +# 2. What are the names of the monsters that are nocturnal? + + $monsters.select { |m| m[:nocturnal]}.collect { |m| m[:name]} + + +# 3. How many legs do all our monsters have? + + $monsters.inject(0) do |total, m| + total += m[:legs] + end + + +# 4. What are the 2 most common dangers and vulnerabilities? + + d_list, v_list = Hash.new(0), Hash.new(0) + + d = $monsters.map { |m| m[:dangers] }.flatten + d_array = d.each { |m| d_list[m] += 1 } + d_list = d_array.sort_by { |k, v| v }[0..1] + + v = $monsters.map { |m| m[:vulnerabilities] }.flatten + v_array = v.each { |m| v_list[m] += 1 } + v_list = v_array.sort_by { |k, v| v }[0..1] + diff --git a/week3/homework/questions.txt b/week3/homework/questions.txt index dfb158d..11deb63 100644 --- a/week3/homework/questions.txt +++ b/week3/homework/questions.txt @@ -1,3 +1,9 @@ +Sarah Wheeler +1/28/14 +Ruby 110 + +Week 3 Homework + Please Read: - Chapter 6 Standard Types - Review Blocks @@ -6,10 +12,81 @@ Please Read: 1. What is a symbol? + A symbol is an object that references a name + (and sometimes strings). Symbols are constant, + unique, and don't change (immutable). They are a way of + referencing an object multiple times without + creating multiple copies/object ids of that object, + which helps reduce the amount a memory a program is + using. For these reasons, they are frequently used as + keys in hashes. + 2. What is the difference between a symbol and a string? + A string can be changed at any time, whereas a symbol + cannot be changed after it is initially created. Another + important distinction is that symbols take up less memory + space than strings do, and they are also faster when it + comes to processing equality comparisons. (Even strings + with the same value must first compare object id's before + comparing the contents of the string itself; symbols have + unique object id's, so processing time is saved with this + step.) + 3. What is a block and how do I call a block? + A block functions similarly to an anonymous method; it is + a piece of code enclosed between either braces ({}) or + "do"/"end" that takes parameters between vertical bars, + and can be passed around to other methods, used for iteration, + or stored in a variable. Blocks are especially useful as + an alternative to loops when combined with the Enumerable + module, or to provide more transactional control (for + example, having a file automatically open/close itself + without explicit instructions from the file user). + + You can call a block by inserting the "yield" statement into + a method and invoking that method, or by simply writing the + block after a method call that uses them. For example, the + .map method can take a block object when it is called: + + array = ["a", "b", "c"] + array.map { |x| "#{x} is a letter"} + + + Blocks aren't executed when Ruby first sees them; instead, + Ruby will wait for the method that the block is being passed + to to be called, and then it will execute the block. + + If you have made your block into a Proc object, you can also + call the block by using the .call method on the proc. + 4. How do I pass a block to a method? What is the method signature? + A block can be passed to a method in a couple ways. + Blocks can be inserted directly into the flow of a method + by using the 'yield' statement, which will initialize the + block before returning to the rest of the method's code. + + A block can also be explicitly passed to a method by including + it as a method parameter and prefixing the name with an ampersand + (as in: &block_name). Ruby will then locate the block, convert it + to a Proc object, and treat it like a variable. You can then call + the block inside of the method by using .call and the block's name + (block_name.call). The method signature--which is the method name + followed by its list of arguments--would look something like this: + + def method_receives_block (var1, var2, &block_name) + block_name.call + end + + This allows the method to use the block as its return value. + 5. Where would you use regular expressions? + + Regular expressions are typically used to search, match, + and replace string sequences. They allow you to define + a specific pattern for your program to look for, and + depending on what method you used in combination with the + regular expression, that particular action will be applied + to the results (or simply be returned to you by the method). diff --git a/week4/homework/questions.txt b/week4/homework/questions.txt index 187b3d3..0f2e041 100644 --- a/week4/homework/questions.txt +++ b/week4/homework/questions.txt @@ -1,14 +1,99 @@ +Sarah Wheeler +2/4/14 +Ruby 110 + +Week 4 Homework + Please Read: -Chapter 10 Basic Input and Output -The Rake Gem: http://rake.rubyforge.org/ +- Chapter 10 Basic Input and Output +- The Rake Gem: http://rake.rubyforge.org/ + 1. How does Ruby read files? + Ruby uses its input features to open a + bidirectional communication stream between + itself and external programs and files. It + then "gets" one item at a time from the + specified resource it is talking to. In a + text file, for example, Ruby's default would + be to read one line of text at a time. Just + as you would tell Ruby which file to open, + it is also a best practice to explicitly close + that file when Ruby has completed a task. + + + 2. How would you output "Hello World!" to a file called my_output.txt? + Assuming that the file didn't already exist, + I would start by creating a file object and + passing it the file name (my_output.txt) and + a mode string. Next, I would use the 'puts' + method to give the file the string I wanted + to be inserted. Once that was done, I would + then close the file. My resulting code would + look like this: + + file = File.new("my_output.txt", "w") + file.puts "Hello World!" + file.close + + However, this code could be improved by + incorporating a block, which would + automatically close the file for us even if + errors occurred: + + File.open("my_output.txt", "w") do |file| + puts "Hello World!" + end + + + 3. What is the Directory class and what is it used for? + The Directory, or Dir class, creates objects + that represent directories (aka folders). + This class allows you to create, delete, and + edit directories. It also gives Ruby a way + to navigate to and through directories so + that you can access locations outside of your + current working directory. The Enumerable + module can also be mixed in to allow for + iteration through directories and the files + they contain. + + + 4. What is an IO object? + An IO object establishes an input/output + connection between Ruby and another resource, + such as a text file or a URL. IO objects + are meant to be read or written to. A simple + example is the Ruby command line: this allows + you to type in your input, which Ruby will + interpret before outputting the returning + information to you. + + + 5. What is rake and what is it used for? What is a rake task? + Rake is a former gem (now included with + the base Ruby language) that allows you to + build and test Ruby frameworks. It is commonly + used with Rails, and uses its task feature to + help automate the creation (or deletion) of + files. Like RSpec, Rake is a domain specific + language, and is similar to utilities like + Make and Ant. + + All Rake code goes into an extensionless file + called Rakefile, which is made up of Rake tasks. + A Rake task is simply a chunk of code that can + be called with 'rake' in the command line. For + example, a ":delete_gitignore_files" task could + be run by entering "rake delete_gitignore_files", + which would use the code in your task script to + delete files ending in .gitignore. \ No newline at end of file diff --git a/week4/homework/worker.rb b/week4/homework/worker.rb new file mode 100644 index 0000000..6c4212d --- /dev/null +++ b/week4/homework/worker.rb @@ -0,0 +1,19 @@ +class Worker + + # Solution for first 3 tests: + # def self.work + # yield + # end + + def self.work(num=1) + result = nil + num.times { |current| result = yield(current) } + result + end + + # After running into trouble with the .times method, I based my + # solution for test #3 on the helpful explanations from this + # StackOverflow question: + # http://stackoverflow.com/questions/20182646/ruby-yield-called-from-within-integertimes-not-returning-the-evaluated-block + +end \ No newline at end of file diff --git a/week5/exercises/rakefile.rb b/week5/exercises/rakefile.rb new file mode 100644 index 0000000..736dc7f --- /dev/null +++ b/week5/exercises/rakefile.rb @@ -0,0 +1,25 @@ +desc "Prints all names in names file" +task :print_names do + File.open("names", "r") do |f| + line = f.readlines + puts line + end +end + +desc "Creates and moves to the class directory." +task :create_class_dir do + Dir.mkdir("class") unless Dir.exists?("class") + Dir.chdir("class") +end + +desc "Creates student directories" +task :create_student_dir => [:create_class_dir] do + File.open("../names", "r") do |f| + f.each do |line| + line.chomp! + Dir.mkdir("#{line}") + # Renee's version: + # Dir.mkdir line.chomp unless Dir.exists? line.chomp + end + end +end \ No newline at end of file diff --git a/week6/homework/lib/sarah_gem.rb b/week6/homework/lib/sarah_gem.rb new file mode 100644 index 0000000..217e34b --- /dev/null +++ b/week6/homework/lib/sarah_gem.rb @@ -0,0 +1 @@ +puts "Hello World!" diff --git a/week6/homework/sarah_gem-0.0.0.gem b/week6/homework/sarah_gem-0.0.0.gem new file mode 100644 index 0000000..2f37340 Binary files /dev/null and b/week6/homework/sarah_gem-0.0.0.gem differ diff --git a/week6/homework/sarah_gem-0.0.0.gemspec b/week6/homework/sarah_gem-0.0.0.gemspec new file mode 100644 index 0000000..967a320 --- /dev/null +++ b/week6/homework/sarah_gem-0.0.0.gemspec @@ -0,0 +1,14 @@ +Gem::Specification.new do |s| + s.name = "sarah_gem" + s.version = "0.0.0" + s.date = "2014-02-19" + s.summary = "Making a Test Gem" + s.description = "A gem for testing my gem-making skills." + s.authors = ["Sarah W."] + s.email = "sarahcwheeler@gmail.com" + s.homepage = "http://rubygems.org/gems/sarah_gem" + s.licenses = ['MIT'] + s.files = ["lib/sarah_gem.rb"] +end + + diff --git a/week7/exercises/features/step_definitions/converter.rb b/week7/exercises/features/step_definitions/converter.rb new file mode 100644 index 0000000..5f03ef7 --- /dev/null +++ b/week7/exercises/features/step_definitions/converter.rb @@ -0,0 +1,23 @@ +class Converter + + attr_accessor :type + + def initialize value + @value = value.to_f + end + + def convert + send "#{@type}_converter" + end + +private + + def Fahrenheit_converter + (@value * (9.0/5.0) + 32.0).round(1) + end + + def Celsius_converter + (@value * (9.0/5.0) + 32.0).round(1) + end + +end \ No newline at end of file diff --git a/week7/exercises/features/step_definitions/converter_steps.rb b/week7/exercises/features/step_definitions/converter_steps.rb new file mode 100644 index 0000000..6440dda --- /dev/null +++ b/week7/exercises/features/step_definitions/converter_steps.rb @@ -0,0 +1,15 @@ +Given(/^I have entered (\d+) into the converter$/) do |arg1| + @converter = Converter.new arg1 +end + +Given(/^I set the type to "(.*?)"$/) do |type| + @converter.type = type +end + +When(/^I press convert$/) do + @result = @converter.convert +end + +Then(//) do |arg1, arg2| + @result.should eq "".to_f +end diff --git a/week7/homework/features/step_definitions/pirate.rb b/week7/homework/features/step_definitions/pirate.rb new file mode 100644 index 0000000..5fa68c2 --- /dev/null +++ b/week7/homework/features/step_definitions/pirate.rb @@ -0,0 +1,10 @@ +class PirateTranslator + + def initialize + end + + def send method=(), arg + "Ahoy Matey\n Shiber Me Timbers You Scurvey Dogs!!" + end + +end diff --git a/week7/homework/features/step_definitions/pirate_steps.rb b/week7/homework/features/step_definitions/pirate_steps.rb index faf1a7f..93c7660 100644 --- a/week7/homework/features/step_definitions/pirate_steps.rb +++ b/week7/homework/features/step_definitions/pirate_steps.rb @@ -5,15 +5,15 @@ Blimey /^I (\w+) '(.+)'$/ do |method, arg| @translator.send(method, arg) end - +# Then Letgoandhaul /^I hit (\w+)$/ do |arg| @result = @translator.send(arg) end - +# Then Letgoandhaul /^it prints out '(.+)'$/ do |arg| @result.split("\n ").first.should == arg end - +# Then Letgoandhaul /^it also prints '(.+)'$/ do |arg| @result.split("\n ").last.should == arg end diff --git a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb index a3287c1..a9bd88e 100644 --- a/week7/homework/features/step_definitions/tic-tac-toe-steps.rb +++ b/week7/homework/features/step_definitions/tic-tac-toe-steps.rb @@ -35,7 +35,7 @@ Then /^the computer prints "(.*?)"$/ do |arg1| @game.should_receive(:puts).with(arg1) - @game.indicate_palyer_turn + @game.indicate_player_turn end Then /^waits for my input of "(.*?)"$/ do |arg1| diff --git a/week7/homework/features/step_definitions/tic-tac-toe.rb b/week7/homework/features/step_definitions/tic-tac-toe.rb new file mode 100644 index 0000000..2af13b1 --- /dev/null +++ b/week7/homework/features/step_definitions/tic-tac-toe.rb @@ -0,0 +1,127 @@ +class TicTacToe + + attr_accessor :player, :player_symbol, :computer_symbol, :open_spots, :board, :com_turn, :winner + + SYMBOLS =[:X, :O] + + WINS = [ + [:A1, :A2, :A3], + [:A1, :B2, :C3], + [:A1, :B1, :C1], + [:A2, :B2, :C2], + [:A3, :B3, :C3], + [:B1, :B2, :B3], + [:C1, :C2, :C3], + [:C1, :B2, :A3] + ] + + @@turn = 0 + @@players = [@player, "Computer"] + + def initialize name="", player_symbol=nil + @player = name.to_s.capitalize + @player_symbol = player_symbol + @computer_symbol = computer_symbol + @com_turn = @current_player + @winner = winner + @open_spots = [:A1, :A2, :A3, :B1, :B2, :B3, :C1, :C2, :C3] + @board = {:A1 => " ", :A2 => " ", :A3 => " ", :B1 => " ", :B2 => " ", :B3 => " ", :C1 => " ", :C2 => " ", :C3 => " " } + + # Assign a symbol to each player + symbols = SYMBOLS.shuffle + if @player_symbol == nil + @player_symbol = symbols.shuffle.pop + else + symbols.delete(player_symbol) + end + @computer_symbol = symbols.pop + end + + def welcome_player + "Welcome #{@player}" + end + + def current_player + @current_player = @com_turn ? "Computer" : @player + end + + def indicate_player_turn + "#{@current_player}'s Move:" + end + + def get_player_move(move = gets.chomp) + move.upcase.to_sym + end + + def player_move + @player_move = get_player_move.to_sym + if @board[@player_move] != " " + message = no_move + else + @board[@player_move] = @player_symbol.to_s + @open_spots.delete(@player_move) + @com_turn = true + @player_move + end + end + + def no_move + puts "No bueno--try one of these: \n #{@open_spots.join(", ")}" + player_move + end + + def computer_move + move = @open_spots.shuffle.pop + @board[move] = @computer_symbol.to_s + @com_turn = false + move.to_sym + end + + def current_state + board_status = " A | B | C "\ + "1 | #{@board.values_at(:A1)[0]} | #{@board.values_at(:B1)[0]} | #{@board.values_at(:C1)[0]}"\ + " |--------------"\ + "2 | #{@board.values_at(:A2)[0]} | #{@board.values_at(:B2)[0]} | #{@board.values_at(:C2)[0]}"\ + " |--------------"\ + "3 | #{@board.values_at(:A3)[0]} | #{@board.values_at(:B2)[0]} | #{@board.values_at(:C3)[0]}" + end + + def board + @board + end + + + def determine_winner + WINS.each do |a, b, c| + if (@board[a] == @board[b]) && (@board[a] == @board[c]) + sym = @board[a] + if sym == @player_symbol + @winner = @player + elsif sym == @computer_symbol + @winner = "Computer" + end + end + end + end + + def player_won? + @winner = @player ? true : false + end + + def over? + @winner != "" ? true : false + end + + def spots_open? + @board.has_value?(" ") ? true : false + end + + def draw? + if self.spots_open? + return false + else + determine_winner + @winner = "" ? true : false + end + end +end \ No newline at end of file diff --git a/week7/homework/play_game.rb b/week7/homework/play_game.rb index 0535830..7b99f10 100644 --- a/week7/homework/play_game.rb +++ b/week7/homework/play_game.rb @@ -10,7 +10,7 @@ when "Computer" @game.computer_move when @game.player - @game.indicate_palyer_turn + @game.indicate_player_turn @game.player_move end puts @game.current_state diff --git a/week7/homework/questions.txt b/week7/homework/questions.txt index d55387d..cce3372 100644 --- a/week7/homework/questions.txt +++ b/week7/homework/questions.txt @@ -1,9 +1,73 @@ +Sarah Wheeler +2/26/14 +Ruby 110 + + Week 7 Homework Please Read Chapters 23 and 24 DuckTyping and MetaProgramming Questions: 1. What is method_missing and how can it be used? -2. What is and Eigenclass and what is it used for? Where Do Singleton methods live? -3. When would you use DuckTypeing? How would you use it to improve your code? + + The method_missing method is an alternative to having + Ruby raise a NoMethodError when an object is unable to + locate a method in its class hierarchy. When you provide + a definition for method_missing in a class you've written, + you can customize what code runs when Ruby can't locate + the method you've invoked. For example, you might set + method_missing to output an error message to the user like + "This method does not exist." + +2. What is an Eigenclass and what is it used for? Where do Singleton methods live? + + An eigenclass (or singleton class) is an anonymous class that + Ruby automatically creates for objects with singleton methods + attached to them. It redesignates itself as the class for that + object (making the object's original class its superclass), + and ensures that both the object's instance and singleton + methods will be included in the method look-up path. Singleton + methods live inside the eigenclass. + +3. When would you use ducktyping? How would you use it to improve your code? + + As a product of Ruby's dynamically-typed nature, ducktyping + allows you to keep your code flexible and easy to change. + Because you don't have to specify a type when you create a + variable--and because its type is almost never the same as + its class--Ruby will allow you to easily change variable + types without necessarily breaking methods, or the overall + structure of your code. + + In a practical sense, this makes ducktyping a good choice + for tests (it allows you to create loosely-defined + representations of objects), and teaches you that there's not + much value in testing the class of an object (since it really + only matters what it does). It can also improve your code's + maintainability; because type changes are so straightforward + to implement, you can make drastic improvements to your code + on the fly. + 4. What is the difference between a class method and an instance method? What is the difference between instance_eval and class_eval? + + Any method that can be called on a class is a class method; + any method that can be called on an instance is an instance + method. Besides differing in the kind of object they are + invoked on, class methods are also defined using the 'self.method' + syntax, which indicates that the method is called on the class + object itself, and not an instance. + + Class_eval differs from instance_eval in that it sets up method + definitions to define instance methods (as if you were in the + body of a class definition). Calling instance_eval, on the other + hand, sets up the definition environment to create class methods + (as though you were in a "singleton class of self", p. 380). + Given what they do, their names are actually quite misleading. + 5. What is the difference between a singleton class and a singleton method? + + A singleton method is a method that is created just for a specific + object, and is not available to other objects of that same class. + In comparison, a singleton class is created to house any singleton + methods that might exist for an object. The former creates a + flexible method, and the latter makes that method work within the + wider scheme of the method look-up paths. \ No newline at end of file