SlideShare a Scribd company logo
1 of 17
Code Smells & Refactoring
by Carlos Mourullo
Who I am?
carlosmourullo@gmail.com
@kmur48
Spanish guy who is trying to grow personally and professionally, little by little,
every day.
When the people ask me what I do I usually say “I solve problems”.
I’m also a music lover, tennis player and bike rider.
Where I’m working?
We are hiring!!! We are hiring!!!
Boy Scout rule
“Always leave the playground cleaner than
you found it” [Uncle Bob]
But!!
 What is the playground?
 What does clean mean?
For me
 Is the lines that you need to
modify to include a new
functionality
 Easy to understand and
modify
Comments
We use these when the code is not very good / easy to
understand… Whenever you feel the need to comment on
something, write a method!
public function printOwing($amount) {
$this->printBanner();
//print details
echo "name: $this->name n";
echo "amount: $amount n";
}
public function printOwing($amount) {
$this->printBanner();
$this->printDetails($amount);
}
public function printDetails($amount) {
echo "name: $this->name n";
echo "amount: $amount n";
}
How?
 Extract Method (use good naming, please)
Duplicate code
Find a way to extract this piece of code: duplicate,
unrelated class or similar
How?
 Duplicate: use Extract Method and invoke the code from both places
 Two unrelated classes: consider using Extract Class
 Similar: you can use Form Template Method
Long method
Longer = more difficult to understand [switch context]
How?
 Use Extract Method to extract conditionals and loops also
 If you end up with a lot of parameters, use Replace Temp with Query
$basePrice = $this->_quantity * $this->_item Price;
if ($basePrice > 1000)
return $basePrice * 0.95;
else
return $basePrice * 0.98;
…
if ($this->basePrice() > 1000)
return $this->basePrice() * 0.95;
else
return $this->basePrice() * 0.98;
…
private function basePrice() {
return $this->_quantity * $this->_item Price;
}
Data clumps
Group of three or four data items together in many
places
How?
 Use Extract Class to turn clumps into an object. One immediate benefit is
that you can simplify method calling
Data class
Class that only has getting and setting. Give it some
responsibility!
How?
 Look for where getting/settings are used by other classes, them try to use
Move Method or Extract Method
Speculative generality
Solve today’s problems, not the future ones!
Sometimes we create some new cases to handle
things that aren’t required
How?
Delete!!
 Remove Parameters
 Collapse Hierarchy
Divergent changes
One class that is commonly changed in different
ways for different reasons
E.g. change your DB or use a new payment system
How?
 Separate these divergent responsibilities. Sometimes two objects are better
than one, use Extract Class
Shotgun Surgery
Every time you make any kind of change you have to
make a lot of little changes to a lot of different
classes… easy to miss something
How?
 Move Method
 Move Field to put all changes into a single class
Boy Scout rule
Deciding when to start refactoring, and when to stop is just as important to the
refactoring process as knowing how to operate the mechanics of a refactoring
If it ain’t broke, don’t fix it!
Don’t go too far
RESPECT the work of others
Thanks!!
Bibliography
 http://martinfowler.com/books/refactoring.html
 https://www.amazon.co.uk/Clean-Code-Handbook-Software-
Craftsmanship/dp/0132350882
 https://medium.com/@elmendalerenda/if-it-s-not-broke-don-t-fix-it-
3a11d4170ec4#.k2eew8whi
 https://blog.codinghorror.com/code-smells/
 http://www.industriallogic.com/wp-
content/uploads/2005/09/smellstorefactorings.pdf
 https://sourcemaking.com/refactoring/smells
 p3Hotels - http://www.p3hotels.com/
 https://jobbio.com/ie/p3hotels-careers
 GTS - http://www.goodtravelsoftware.com/
 http://www.goodtravelsoftware.com/jobs.php
Hiring!!

More Related Content

Similar to Code smells and refactoring

Ruby, Turkee and Mechanical Turk
Ruby, Turkee and Mechanical TurkRuby, Turkee and Mechanical Turk
Ruby, Turkee and Mechanical TurkJim Jones
 
Data Exploration with Apache Drill: Day 2
Data Exploration with Apache Drill: Day 2Data Exploration with Apache Drill: Day 2
Data Exploration with Apache Drill: Day 2Charles Givre
 
Task 03
Task 03Task 03
Task 03EdiPHP
 
Ruby meetup evolution of bof search
Ruby meetup   evolution of bof search Ruby meetup   evolution of bof search
Ruby meetup evolution of bof search Miha Mencin
 
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptxINTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptxDeepasCSE
 
Vision academy classes bcs_bca_bba_sybba_php
Vision academy  classes bcs_bca_bba_sybba_phpVision academy  classes bcs_bca_bba_sybba_php
Vision academy classes bcs_bca_bba_sybba_phpsachin892777
 
Company segmentation - an approach with R
Company segmentation - an approach with RCompany segmentation - an approach with R
Company segmentation - an approach with RCasper Crause
 
PrestaShop Kathmandu Ecommerce Meetup #2
PrestaShop Kathmandu Ecommerce Meetup #2PrestaShop Kathmandu Ecommerce Meetup #2
PrestaShop Kathmandu Ecommerce Meetup #2Hem Pokhrel
 
lec_4_data_structures_and_algorithm_analysis.ppt
lec_4_data_structures_and_algorithm_analysis.pptlec_4_data_structures_and_algorithm_analysis.ppt
lec_4_data_structures_and_algorithm_analysis.pptMard Geer
 
lec_4_data_structures_and_algorithm_analysis.ppt
lec_4_data_structures_and_algorithm_analysis.pptlec_4_data_structures_and_algorithm_analysis.ppt
lec_4_data_structures_and_algorithm_analysis.pptSourabhPal46
 
Introduction to Machine Learning
Introduction to Machine LearningIntroduction to Machine Learning
Introduction to Machine LearningShahar Cohen
 
AST + Better Reflection (PHP Benelux 2016 Unconference)
AST + Better Reflection (PHP Benelux 2016 Unconference)AST + Better Reflection (PHP Benelux 2016 Unconference)
AST + Better Reflection (PHP Benelux 2016 Unconference)James Titcumb
 
Forms, Getting Your Money's Worth
Forms, Getting Your Money's WorthForms, Getting Your Money's Worth
Forms, Getting Your Money's WorthAlex Gaynor
 
Practical Predictive Modeling in Python
Practical Predictive Modeling in PythonPractical Predictive Modeling in Python
Practical Predictive Modeling in PythonRobert Dempsey
 
Measures of central tendency by maria diza c. febrio
Measures of central tendency by maria diza c. febrioMeasures of central tendency by maria diza c. febrio
Measures of central tendency by maria diza c. febriomariadiza
 

Similar to Code smells and refactoring (20)

Refactoring
RefactoringRefactoring
Refactoring
 
Ruby, Turkee and Mechanical Turk
Ruby, Turkee and Mechanical TurkRuby, Turkee and Mechanical Turk
Ruby, Turkee and Mechanical Turk
 
Data Exploration with Apache Drill: Day 2
Data Exploration with Apache Drill: Day 2Data Exploration with Apache Drill: Day 2
Data Exploration with Apache Drill: Day 2
 
Task 03
Task 03Task 03
Task 03
 
Ruby meetup evolution of bof search
Ruby meetup   evolution of bof search Ruby meetup   evolution of bof search
Ruby meetup evolution of bof search
 
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptxINTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
INTRODUCTION TO OBJECT ORIENTED PROGRAMMING.pptx
 
Vision academy classes bcs_bca_bba_sybba_php
Vision academy  classes bcs_bca_bba_sybba_phpVision academy  classes bcs_bca_bba_sybba_php
Vision academy classes bcs_bca_bba_sybba_php
 
Company segmentation - an approach with R
Company segmentation - an approach with RCompany segmentation - an approach with R
Company segmentation - an approach with R
 
PrestaShop Kathmandu Ecommerce Meetup #2
PrestaShop Kathmandu Ecommerce Meetup #2PrestaShop Kathmandu Ecommerce Meetup #2
PrestaShop Kathmandu Ecommerce Meetup #2
 
Refactoring
RefactoringRefactoring
Refactoring
 
Composing method
Composing methodComposing method
Composing method
 
lec_4_data_structures_and_algorithm_analysis.ppt
lec_4_data_structures_and_algorithm_analysis.pptlec_4_data_structures_and_algorithm_analysis.ppt
lec_4_data_structures_and_algorithm_analysis.ppt
 
lec_4_data_structures_and_algorithm_analysis.ppt
lec_4_data_structures_and_algorithm_analysis.pptlec_4_data_structures_and_algorithm_analysis.ppt
lec_4_data_structures_and_algorithm_analysis.ppt
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
Introduction to Machine Learning
Introduction to Machine LearningIntroduction to Machine Learning
Introduction to Machine Learning
 
AST + Better Reflection (PHP Benelux 2016 Unconference)
AST + Better Reflection (PHP Benelux 2016 Unconference)AST + Better Reflection (PHP Benelux 2016 Unconference)
AST + Better Reflection (PHP Benelux 2016 Unconference)
 
Forms, Getting Your Money's Worth
Forms, Getting Your Money's WorthForms, Getting Your Money's Worth
Forms, Getting Your Money's Worth
 
Practical Predictive Modeling in Python
Practical Predictive Modeling in PythonPractical Predictive Modeling in Python
Practical Predictive Modeling in Python
 
Agile database access with CakePHP 3
Agile database access with CakePHP 3Agile database access with CakePHP 3
Agile database access with CakePHP 3
 
Measures of central tendency by maria diza c. febrio
Measures of central tendency by maria diza c. febrioMeasures of central tendency by maria diza c. febrio
Measures of central tendency by maria diza c. febrio
 

Recently uploaded

Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Anthony Dahanne
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencessuser9e7c64
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 

Recently uploaded (20)

Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conference
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 

Code smells and refactoring

  • 1. Code Smells & Refactoring by Carlos Mourullo
  • 2. Who I am? carlosmourullo@gmail.com @kmur48 Spanish guy who is trying to grow personally and professionally, little by little, every day. When the people ask me what I do I usually say “I solve problems”. I’m also a music lover, tennis player and bike rider.
  • 3. Where I’m working? We are hiring!!! We are hiring!!!
  • 4. Boy Scout rule “Always leave the playground cleaner than you found it” [Uncle Bob] But!!  What is the playground?  What does clean mean? For me  Is the lines that you need to modify to include a new functionality  Easy to understand and modify
  • 5. Comments We use these when the code is not very good / easy to understand… Whenever you feel the need to comment on something, write a method! public function printOwing($amount) { $this->printBanner(); //print details echo "name: $this->name n"; echo "amount: $amount n"; } public function printOwing($amount) { $this->printBanner(); $this->printDetails($amount); } public function printDetails($amount) { echo "name: $this->name n"; echo "amount: $amount n"; } How?  Extract Method (use good naming, please)
  • 6. Duplicate code Find a way to extract this piece of code: duplicate, unrelated class or similar How?  Duplicate: use Extract Method and invoke the code from both places  Two unrelated classes: consider using Extract Class  Similar: you can use Form Template Method
  • 7.
  • 8. Long method Longer = more difficult to understand [switch context] How?  Use Extract Method to extract conditionals and loops also  If you end up with a lot of parameters, use Replace Temp with Query $basePrice = $this->_quantity * $this->_item Price; if ($basePrice > 1000) return $basePrice * 0.95; else return $basePrice * 0.98; … if ($this->basePrice() > 1000) return $this->basePrice() * 0.95; else return $this->basePrice() * 0.98; … private function basePrice() { return $this->_quantity * $this->_item Price; }
  • 9. Data clumps Group of three or four data items together in many places How?  Use Extract Class to turn clumps into an object. One immediate benefit is that you can simplify method calling
  • 10. Data class Class that only has getting and setting. Give it some responsibility! How?  Look for where getting/settings are used by other classes, them try to use Move Method or Extract Method
  • 11. Speculative generality Solve today’s problems, not the future ones! Sometimes we create some new cases to handle things that aren’t required How? Delete!!  Remove Parameters  Collapse Hierarchy
  • 12. Divergent changes One class that is commonly changed in different ways for different reasons E.g. change your DB or use a new payment system How?  Separate these divergent responsibilities. Sometimes two objects are better than one, use Extract Class
  • 13. Shotgun Surgery Every time you make any kind of change you have to make a lot of little changes to a lot of different classes… easy to miss something How?  Move Method  Move Field to put all changes into a single class
  • 14. Boy Scout rule Deciding when to start refactoring, and when to stop is just as important to the refactoring process as knowing how to operate the mechanics of a refactoring
  • 15. If it ain’t broke, don’t fix it! Don’t go too far RESPECT the work of others Thanks!!
  • 16. Bibliography  http://martinfowler.com/books/refactoring.html  https://www.amazon.co.uk/Clean-Code-Handbook-Software- Craftsmanship/dp/0132350882  https://medium.com/@elmendalerenda/if-it-s-not-broke-don-t-fix-it- 3a11d4170ec4#.k2eew8whi  https://blog.codinghorror.com/code-smells/  http://www.industriallogic.com/wp- content/uploads/2005/09/smellstorefactorings.pdf  https://sourcemaking.com/refactoring/smells
  • 17.  p3Hotels - http://www.p3hotels.com/  https://jobbio.com/ie/p3hotels-careers  GTS - http://www.goodtravelsoftware.com/  http://www.goodtravelsoftware.com/jobs.php Hiring!!

Editor's Notes

  1. This quote is full of meaning but it’s ambiguous and need some explanation, some context. Over the years, I went to meetups or conferences and I hear about code patterns or design patterns that you should use. And when I back to coding I didn't really know when to start to apply this patterns This code smells help me to wrong and I hope can help you too. When you are writing code, can discover really small things that indicate really big problems.
  2. The real key to making it easy to understand is a good naming. If you have a good name, you don’t need to look at the body.
  3. The longer a procedure is, the more difficult it is to understand because you need to switch content to see what the procedure does.
  4. “Oh I think we’ll need the ability to do this kind of thing someday”.
  5. When we make a change we want to be able to jump to a single clear point in the system and make the change. If we can’t, we identify a smell. When you make changes to a class you need to also modify other parts of the class, otherwise it may contain too much unrelated functionality.
  6. Shotgun surgery is similar to divergent change but it is the opposite. You must change lots of pieces of code in different places in order to add a new feature or extended piece of behavior.
  7. So! Back to the Boy Scout rule … Knowing when to start, and knowing when to stop
  8. When, in your editor, you open code that is already in production, you are looking at code that someone spent time and money on and probably someone is using it right now. It’s important for someone, for whatever reason.