13 Replies - 1115 Views - Last Post: 30 January 2014 - 10:46 PM Rate Topic: -----

#1 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Calling a method within a method

Posted 29 January 2014 - 03:08 PM

On line 52 of this I would like to adopt the functionality of #temp_manager within the update_temp method. Through my research it seems that I need to turn both update_temp and temp_manger into class methods (House.update_temp and House.temp_manger). 1. Is this good style? and 2. Should I make temp_manager a class of its own? Thanks for any help.


class House

	def initialize(current_temp, minimum_temp, maximum_temp)
		@current_temp = current_temp
		@minimum_temp = minimum_temp
		@maximum_temp = maximum_temp
		@heater_on = false
		@ac_on = false
		puts "This new house has a current temperature of #{current_temp}. The heater is set to #{@heater_on}\nand the ac is set to #{@ac_on}."
		puts "This new house's minimum temp setting is #{minimum_temp}."
		puts "This new house's maximum temp setting is #{maximum_temp}."
	    puts "----------------"
	end

    def toggle_heater # turning the heater on automatically sets ac_on to false
    	@heater_on = @heater_on.!
    	if @heater_on == true
    	    @ac_on = false
    	    puts "The heater has been set to #{@heater_on} and the ac has automatically been set to #{@ac_on}."
    	elsif @heater_on == false
    		puts "The heater has been set to #{@heater_on}."
    	end
    	puts "----------------"
    end

    def toggle_ac #turning ac on automaticall set @heater_on to false
    	@ac_on = @ac_on.!
    	if @ac_on == true
    	   @heater_on = false
    	   puts "The ac has been set to #{@ac_on} and the heater has automatically been set to #{@heater_on}."
    	elsif @ac_on == false
    	   puts "The ac has been set to #{@ac_on}."
    	end
    	puts "----------------"
    end

    def update_temp!
    	# when the heat_on this increases the temp by 1
    	if @heater_on == true
    	   @current_temp += 1 
    	   puts "the current temperature has been increased to #{@current_temp}."
    	   puts "----------------"
    	end
    	
    	if @ac_on == true
    	   @current_temp -= 2 
    	   puts "The current temperture has been decreased to #{@current_temp}."
    	   puts "----------------"
    	end
    	#temp_manager
    end

    def temp_manager### PERHAPS THIS SHOULD BE TURNED INTO A CLASS OF IT"S OWN?
    	if @current_temp > @maximum_temp
    		toggle_heater
    		puts "the current temperature has risen above the maximum temp: the ac has been set to #{ac_on} and the heater has been set to #{heater_on}."
    		puts "----------------"
    	end

    	if @current_temp < @maximum_temp
    		toggle_heater
    		puts "the current temperature has fallen below the minimum temp: the heater has been set to #{heater_on} and the ac has been set to #{ac_on}."
    		puts "----------------"
    	end
    	# When the current_temp rises above the maximum_temp, the air conditioner turns on and the heater should be off.
        # When the current_temp falls below the minimum_temp, the heater turns on and the air conditioner should be off.
    end
end


h = my_house = House.new(71, 62, 72)
h.toggle_heater
h.toggle_heater
h.toggle_heater

h.toggle_ac
h.toggle_ac
h.toggle_ac

h.toggle_heater
h.toggle_ac

h.update_temp!
h.update_temp!

h.toggle_heater
h.update_temp!
h.update_temp!



Is This A Good Question/Topic? 0
  • +

Replies To: Calling a method within a method

#2 xclite  Icon User is offline

  • LIKE A BOSS
  • member icon


Reputation: 911
  • View blog
  • Posts: 3,179
  • Joined: 12-May 09

Re: Calling a method within a method

Posted 29 January 2014 - 03:14 PM

You might consider creating a module if this was common logic, but this is specific to this class. I don't see why you think they need to be class methods - you should be able to call temp_manager from an instance of House, inside of update_temp.

There's a lot, stylistically, that I'll comment on here.

First, the name temp_manager reflects that you don't really know what that method is responsible for. Who calls it? Under what circumstances does it act? The vague name you've assigned to it isn't helpful and allows you to wiggle out of proper abstractions.

The way I'm looking at it, the logic in temp_manager is just another part of update_temp and belongs there, though there other ways to refactor that, depending on your goals.

Now, let's talk about some more style:
In toggle_heater:
Instead of @heater_on = @heater_on.!, why not @heater_on = !@heater_on?
Instead of if @heater_on == true do if @heater_on
Instead of checking for true, then elsif checking for false, check for true and then else. It can only end up evaluating to false if it didn't evaluate to true.

Same comments for toggle_ac and update_temp!.

This post has been edited by xclite: 29 January 2014 - 03:16 PM

Was This Post Helpful? 3
  • +
  • -

#3 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Re: Calling a method within a method

Posted 29 January 2014 - 05:33 PM

Thanks for the incites. Very helpful
Was This Post Helpful? 0
  • +
  • -

#4 Lemur  Icon User is offline

  • Pragmatism over Dogma
  • member icon


Reputation: 1377
  • View blog
  • Posts: 3,501
  • Joined: 28-November 09

Re: Calling a method within a method

Posted 29 January 2014 - 05:59 PM

Refactor:
class House

  def initialize(current: 0, min: 0, max: 0)
    @current_temp = current
    @minimum_temp = min
    @maximum_temp = max
    @heater_on    = false
    @ac_on        = false
  end

  def toggle_heater # turning the heater on automatically sets ac_on to false
    @heater_on = !@heater_on
    @ac_on = false if @heater
  end

  def toggle_ac
    @ac_on = !@ac_on
  end

  def update_temp!
    @current_temp += 1 if @heater_on
    @current_temp -= 2 if @ac_on
  end

  def temp_manager
    toggle_heater if @current_temp > @maximum_temp
    toggle_ac if @current_temp < @maximum_temp
  end

  def to_s
    "Current: #{@current_temp}\n" +
    "Min:     #{@minimum_temp}\n" +
    "Max:     #{@maximum_temp}\n" +
    "Heater:  #{@heater_on}\n" +
    "AC:      #{@ac_on}"
  end
end


h = House.new(current: 71, min: 62, max: 72)
h.toggle_heater
h.toggle_heater
h.toggle_heater

puts h

h.toggle_ac
h.toggle_ac
h.toggle_ac

puts h

h.toggle_heater
h.toggle_ac

puts h

h.update_temp!
h.update_temp!

puts h

h.toggle_heater
h.update_temp!
h.update_temp!

puts h



The things to remember here are:

  • You really should implement a to_s method
  • All that extra cruft and text output completely defeats the purpose of single responsibility methods
  • Your class needs to do only what it absolutely needs to do, meaning all the extra puts get in the way
  • The temp manager may need another class, but at this point it doesn't warrant it
  • Unless a value is nil or false, it will be as such. @var == true is redundant
  • All of those methods are bang methods, as they all mutate the state.
  • Keyword Args in Ruby 2.0+ are great to simplify things and give meaning to instantiators.

Was This Post Helpful? 3
  • +
  • -

#5 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Re: Calling a method within a method

Posted 29 January 2014 - 06:30 PM

Thanks!!!
Was This Post Helpful? 0
  • +
  • -

#6 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Re: Calling a method within a method

Posted 29 January 2014 - 08:59 PM

For Some reason update_temp! wont decrease the temp when ac_on = true. Line 54 trips toggle_ac setting ac_on to true. update temp! should decrease the temp from that point. I don;t understand why it is not happening given the statement on line 23.

class House

  def initialize(current: 0, min: 0, max: 0)  # just learned about keyword args. No longer need hash.
    @current_temp = current
    @minimum_temp = min
    @maximum_temp = max
    @heater_on    = false
    @ac_on        = false
  end

  def toggle_heater # turning the heater on automatically sets ac_on to false
    @heater_on = !@heater_on
    @ac_on = false if @heater_on
  end

  def toggle_ac
    @ac_on = !@ac_on
    @heater_on = false if @ac_on
  end

  def update_temp!
    @current_temp += 1 if @heater_on
    @current_temp -= 2 if @ac_on
    toggle_ac if @current_temp > @maximum_temp
    toggle_heater if @current_temp < @maximum_temp
  end

  def to_s # formatted output
    "Current: #{@current_temp}\n" +
    "Min:     #{@minimum_temp}\n" +
    "Max:     #{@maximum_temp}\n" +
    "Heater:  #{@heater_on}\n" +
    "AC:      #{@ac_on}"
  end
end


h = House.new(current: 71, min: 62, max: 72)
puts h

h.toggle_ac
puts h

h.toggle_heater
puts h

h.toggle_ac
puts h

h.toggle_heater
puts h

h.update_temp! # temp increases
h.update_temp! # trips toggle_ac
puts h
h.update_temp! # temp should decrease now - but it doesn't
h.update_temp!
h.update_temp!
h.update_temp!
h.update_temp!
h.update_temp!
puts h              #show the same current temp



Was This Post Helpful? 0
  • +
  • -

#7 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Re: Calling a method within a method

Posted 29 January 2014 - 09:17 PM

oddly enough if I insert puts h after line 57 the temperature decreases by 1 degree. Which is really weird because the temp should decrease if anything by increments of 2.
Was This Post Helpful? 0
  • +
  • -

#8 Lemur  Icon User is offline

  • Pragmatism over Dogma
  • member icon


Reputation: 1377
  • View blog
  • Posts: 3,501
  • Joined: 28-November 09

Re: Calling a method within a method

Posted 29 January 2014 - 10:26 PM

http://www.youtube.c...h?v=jDXsEzOHb2M
http://www.youtube.c...h?v=D9j_Mf91M0I

Both of these will be of substantial help.
Was This Post Helpful? 1
  • +
  • -

#9 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Re: Calling a method within a method

Posted 30 January 2014 - 01:41 PM

Pry seems very cool. I have installed and used it and appreciate the color coding, however I am missing out on a lot of coding context so It currently is a tool that's over my head. I will continue looking into it for sure. I'm still mystified as to why line 23 doesn't seem to be taking effect. It is structured the same way as line 22 and that statement does its job.
Was This Post Helpful? 0
  • +
  • -

#10 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Re: Calling a method within a method

Posted 30 January 2014 - 05:05 PM

Wow...we'll I'm embarrassed. The problem finally caught my eye. Took me forever to see it.
Was This Post Helpful? 1
  • +
  • -

#11 Lemur  Icon User is offline

  • Pragmatism over Dogma
  • member icon


Reputation: 1377
  • View blog
  • Posts: 3,501
  • Joined: 28-November 09

Re: Calling a method within a method

Posted 30 January 2014 - 05:09 PM

View Postheaphyg, on 30 January 2014 - 06:05 PM, said:

Wow...we'll I'm embarrassed. The problem finally caught my eye. Took me forever to see it.


Welcome to the life of every programmer ever.
Was This Post Helpful? 1
  • +
  • -

#12 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Re: Calling a method within a method

Posted 30 January 2014 - 05:40 PM

What is the best way to test the output for something like this. I tried what I usually do but with this concatenated string I get false. I would like to test all of my puts statements and get true returned. I tired a non concatenated version (just a single string) but that doesn't work for me either. This might seem pointless but i'm curious. Thanks.

h = House.new(71,62,72) #1
puts h == "Current: 71" +
          "Min:     62" +
          "Max:     72" +
          "Heater:  false" +
          "AC:      false"    #=> false



Was This Post Helpful? 0
  • +
  • -

#13 Lemur  Icon User is offline

  • Pragmatism over Dogma
  • member icon


Reputation: 1377
  • View blog
  • Posts: 3,501
  • Joined: 28-November 09

Re: Calling a method within a method

Posted 30 January 2014 - 10:43 PM

....that makes no sense. If you want to test, I'd look into getting started on RSPEC as this seems fairly confounded.

Of immediate note if you're bent on that method, you're comparing an object to its' string output, it needs a .to_s on it if that's what you're trying to compare.
Was This Post Helpful? 1
  • +
  • -

#14 heaphyg  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 85
  • Joined: 30-August 13

Re: Calling a method within a method

Posted 30 January 2014 - 10:46 PM

I just figured that out! took me way to long. But thanks for getting back to me and thanks for all the previous advice...huge help
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1