diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 3375fcf20ac..424719304e6 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -468,10 +468,11 @@ module GRPC route = "/#{cls.service_name}/#{name}".to_sym fail "already registered: rpc #{route} from #{spec}" if specs.key? route specs[route] = spec + rpc_name = GenericService.underscore(name.to_s).to_sym if service.is_a?(Class) - handlers[route] = cls.new.method(name.to_s.underscore.to_sym) + handlers[route] = cls.new.method(rpc_name) else - handlers[route] = service.method(name.to_s.underscore.to_sym) + handlers[route] = service.method(rpc_name) end logger.info("handling #{route} with #{handlers[route]}") end diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb index 69076b4c6e8..8ea2c82f171 100644 --- a/src/ruby/lib/grpc/generic/service.rb +++ b/src/ruby/lib/grpc/generic/service.rb @@ -30,24 +30,6 @@ require 'grpc/generic/client_stub' require 'grpc/generic/rpc_desc' -# Extend String to add a method underscore -class String - # creates a new string that is the underscore separate version of this one. - # - # E.g, - # PrintHTML -> print_html - # AMethod -> a_method - # AnRpc -> an_rpc - def underscore - word = dup - word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2') - word.gsub!(/([a-z\d])([A-Z])/, '\1_\2') - word.tr!('-', '_') - word.downcase! - word - end -end - # GRPC contains the General RPC module. module GRPC # Provides behaviour used to implement schema-derived service classes. @@ -55,6 +37,22 @@ module GRPC # Is intended to be used to support both client and server # IDL-schema-derived servers. module GenericService + # creates a new string that is the underscore separate version of s. + # + # E.g, + # PrintHTML -> print_html + # AMethod -> a_method + # AnRpc -> an_rpc + # + # @param s [String] the string to be converted. + def self.underscore(s) + s.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2') + s.gsub!(/([a-z\d])([A-Z])/, '\1_\2') + s.tr!('-', '_') + s.downcase! + s + end + # Used to indicate that a name has already been specified class DuplicateRpcName < StandardError def initialize(name) @@ -171,7 +169,7 @@ module GRPC # Used define_method to add a method for each rpc_desc. Each method # calls the base class method for the given descriptor. descs.each_pair do |name, desc| - mth_name = name.to_s.underscore.to_sym + mth_name = GenericService.underscore(name.to_s).to_sym marshal = desc.marshal_proc unmarshal = desc.unmarshal_proc(:output) route = "/#{route_prefix}/#{name}" @@ -207,7 +205,7 @@ module GRPC # implemented. def assert_rpc_descs_have_methods rpc_descs.each_pair do |m, spec| - mth_name = m.to_s.underscore.to_sym + mth_name = GenericService.underscore(m.to_s).to_sym unless instance_methods.include?(mth_name) fail "#{self} does not provide instance method '#{mth_name}'" end diff --git a/src/ruby/spec/generic/service_spec.rb b/src/ruby/spec/generic/service_spec.rb index e7f5a65d3b3..6cfc34db84d 100644 --- a/src/ruby/spec/generic/service_spec.rb +++ b/src/ruby/spec/generic/service_spec.rb @@ -56,15 +56,6 @@ end GenericService = GRPC::GenericService Dsl = GenericService::Dsl -describe 'String#underscore' do - it 'should convert CamelCase to underscore separated' do - expect('AnRPC'.underscore).to eq('an_rpc') - expect('AMethod'.underscore).to eq('a_method') - expect('PrintHTML'.underscore).to eq('print_html') - expect('PrintHTMLBooks'.underscore).to eq('print_html_books') - end -end - describe Dsl do it 'can be included in new classes' do blk = proc { Class.new { include Dsl } } @@ -73,6 +64,15 @@ describe Dsl do end describe GenericService do + context '#underscore' do + it 'should convert CamelCase to underscore separated' do + expect(GenericService.underscore('AnRPC')).to eq('an_rpc') + expect(GenericService.underscore('AMethod')).to eq('a_method') + expect(GenericService.underscore('PrintHTML')).to eq('print_html') + expect(GenericService.underscore('SeeHTMLBooks')).to eq('see_html_books') + end + end + describe 'including it' do it 'adds a class method, rpc' do c = Class.new do