Introducing the Endless Method in Ruby 3.0
Ruby 3.0 introduces a new feature known as the endless method. This new feature simplifies method definitions by allowing developers to eliminate the traditional end
keyword for closures, using a straightforward =
instead. This is particularly useful for short, simple method definitions. For example:
Traditional Syntax
def available?
!@internal.empty?
end
With Endless Method
def available? = !@internal.any?
Streamline Your Codebase with My Synvert Snippet
To facilitate the transition to this new syntax, I’ve developed a Synvert snippet that automates the refactoring of existing method definitions to adopt the endless method format. You can find this snippet in the Synvert Ruby snippets repository.
The snippet intelligently scans Ruby files to identify and convert eligible traditional method definitions into their more concise endless method counterparts. It’s designed to avoid inappropriate conversions such as those involving setter methods and parallel assignments, ensuring a safe and accurate transformation that maintains the original functionality of your code.
Practical Example: Applying the Snippet
Let’s explore how this snippet can be used on a real-world codebase. I will demonstrate the process on the upgradecode.io
codebase.
Running the Synvert Command
Execute the following command to refactor your code:
synvert-ruby --run ruby/prefer-endless-method
Check the changes using:
git diff
Here’s an example of the transformation in one of the project files:
diff --git a/app/controllers/memberships_controller.rb b/app/controllers/memberships_controller.rb
index 32840b1..69895c2 100644
--- a/app/controllers/memberships_controller.rb
+++ b/app/controllers/memberships_controller.rb
@@ -32,20 +32,14 @@ class MembershipsController < ApplicationController
private
- def process_invitation_acceptance
- if @membership.user == current_user
- @membership.update(invitation_accepted_at: Time.current, status: 'accepted')
- redirect_to organization_path(@membership.organization.slug), notice: "You have successfully joined the organization!"
- else
- redirect_to root_path, alert: "This invitation is not intended for you."
- end
+ def process_invitation_acceptance = if @membership.user == current_user
+ @membership.update(invitation_accepted_at: Time.current, status: 'accepted')
+ redirect_to organization_path(@membership.organization.slug), notice: "You have successfully joined the organization!"
+ else
+ redirect_to root_path, alert: "This invitation is not intended for you."
end
- def set_organization
- @organization = Organization.find_by(slug: params[:organization_id])
- end
+ def set_organization = @organization = Organization.find_by(slug: params[:organization_id])
- def membership_params
- params.require(:membership).permit(:email)
- end
+ def membership_params = params.require(:membership).permit(:email)
end
diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb
index 19a2a54..fc97c36 100644
--- a/app/controllers/organizations_controller.rb
+++ b/app/controllers/organizations_controller.rb
@@ -7,9 +7,7 @@ class OrganizationsController < ApplicationController
@new_organization = Organization.new
end
- def show
- redirect_to organization_projects_path(params[:id])
- end
+ def show = redirect_to organization_projects_path(params[:id])
def create
@new_organization = Organization.new(organization_params)
@@ -22,7 +20,5 @@ class OrganizationsController < ApplicationController
private
- def organization_params
- params.require(:organization).permit(:name)
- end
+ def organization_params = params.require(:organization).permit(:name)
end
Ensuring Code Integrity Post-Refactoring
After applying the snippet, it’s crucial to verify the integrity and functionality of the code:
bundle exec rails test
Conclusion
I hope this snippet facilitates your upgrade to Ruby 3.0 and helps streamline your codebase. If you encounter any issues or have feedback, I am eager to assist. Happy coding!
Prefer endless method by Synvert