很有收获的一天 class_eval + 扩展ActiveRecord::Base

本文介绍了一种简化Ruby中常量及对应描述设置的方法,通过定义`binary_desc`和`const_desc`方法来实现更加直观和易于维护的配置方式。

一直以来,对于一些选项类的操作,会设置常量和对应的描述。典型情况如下:

  CONST_TO_LIST_FOR_NUMBER =   [ 
    ['新建', NEXT_NEW],   
    ['退出', NEXT_EXIT],   
    ['直播分机', NEXT_EXTENSION],
    #  ['语音信箱', NEXT_RECORD],
    ['转人工', NEXT_HUMAN]
  ] 

 而现在更想用形式上更像声明的方式来完成这些设置,于是考虑按validates_xxx的形式完成诸如以下的调用

binary_desc :response_desc, "已回复", "未回复"
const_desc :contact_type_desc, 0 => '没有操作', 1 => '录音', 2=>'SMS', 3 => 'EMAIL'

 前者是针对boolean变量,后者针对有多个值的情况传入一个hash,第一个参数都是要生成的常量+函数名,常量会自动转变成大写。

 

binary_desc相对较简单,

    src = <<-END_SRC   
       #{desc_name.upcase} = [  ['#{true_desc}', true], ['#{false_desc}', false] ] 
    END_SRC
    class_eval src unless const_defined?  desc_name.upcase

 需要注意的是因为true_desc会是中文,所以在#{}两侧要添加单引号。

const_desc相当要复杂些,因为在here doc里面认识外部传入的hash未找到好的办法,目前通过先转成字符串,再在eval时还原出来完成。

    options_arr = (options.map {|key, content|  "#{content}::#{key}"}).join('!')
    src = <<-END_SRC   
      def self.#{desc_name} 
        options_str = '#{options_arr}' 
        options_str.split('!').map {|s| s.split('::') }
      end
    END_SRC
    class_eval src

 join split 和map真的挺好用的。

 

然后要做的事情就是给这两个method找一个存放的地方。

因为很多model类会使用,所以想做成support的形式,感觉放在ActiveRecord::Base是最方便的。于是决定写个rb文件对ActiveRecord::Base进行扩展

active_record_support.rb

class ActiveRecord::Base 
  
  def self.binary_desc(desc_name, true_desc, false_desc)  
      ...
  end  
  
 
  def self.const_desc(desc_name, options = {})
     ...
  end
end

 起初,把这个文件放在config目录下面,同时在environment.rb的最后补充require File.join(File.dirname(__FILE__), 'active_record_support')。运行test和rails都可以成功。

但对于使用了observe的model会出问题。因为require support文件的操作在Rails::Initializer.run之后。这样的话会需要干扰到rails正常的初始化动作才能完成。于是决定还是放到model目录下面去。然后再observer处调用require 'active_record_support'。

 

这样,以后定义常量和对应的描述就可以更轻松一些了。

 

 

 

 

E:/Bitnami/redmine-5.0.3-0/ruby/bin/ruby.exe -x E:\Bitnami\redmine-5.0.3-0\apps\redmine\htdocs\bin\bundle exec E:\Bitnami\redmine-5.0.3-0\ruby\bin\ruby.exe E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/bin/rails server -b 127.0.0.1 -p 3000 -e development Beginning in Rails 4, Rails ships with a `rails` binstub at ./bin/rails that should be used instead of the Bundler-generated `rails` binstub. If you are seeing this message, your binstub at ./bin/rails was generated by Bundler instead of Rails. You might need to regenerate your `rails` binstub locally and add it to source control: rails app:update:bin # Bear in mind this generates other binstubs # too that you may or may not want (like yarn) If you already have Rails binstubs in source control, you might be inadvertently overwriting them during deployment by using bundle install with the --binstubs option. If your application was created prior to Rails 4, here's how to upgrade: bundle config --delete bin # Turn off Bundler's stub generator rails app:update:bin # Use the new Rails executables git add bin # Add bin/ to source control You may need to remove bin/ from your .gitignore as well. When you install a gem whose executable you want to use in your app, generate it and add it to source control: bundle binstubs some-gem-name git add bin/new-executable => Booting Thin => Rails 6.1.7 application starting in development http://127.0.0.1:3000 => Run `bin/rails server --help` for more startup options Please add the following to your Gemfile to avoid polling for changes: gem 'wdm', '>= 0.1.0' if Gem.win_platform? E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activerecord-6.1.7/lib/active_record/dynamic_matchers.rb:22:in `method_missing': undefined method `named_scope' for Issue (call 'Issue.connection' to establish a connection):Class (NoMethodError) from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/lib/redmine_simple_kanban/patches/issue_patch.rb:13:in `block in included' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/lib/redmine_simple_kanban/patches/issue_patch.rb:8:in `class_eval' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/lib/redmine_simple_kanban/patches/issue_patch.rb:8:in `included' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:61:in `include' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:61:in `block (3 levels) in <top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:61:in `class_eval' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:61:in `block (2 levels) in <top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:50:in `each' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:50:in `block in <top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:68:in `block in execute_hook' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:61:in `with_execution_control' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:66:in `execute_hook' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:51:in `each' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/application/finisher.rb:140:in `block in <module:Finisher>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/initializable.rb:32:in `instance_exec' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/initializable.rb:32:in `run' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/initializable.rb:61:in `block in run_initializers' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:347:in `each' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:347:in `call' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/initializable.rb:60:in `run_initializers' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/application.rb:391:in `initialize!' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/config/environment.rb:16:in `<top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/dependencies.rb:332:in `block in require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/dependencies.rb:299:in `load_dependency' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/dependencies.rb:332:in `require' from config.ru:3:in `block in <main>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/builder.rb:116:in `eval' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/builder.rb:116:in `new_from_string' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/builder.rb:105:in `load_file' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/builder.rb:66:in `parse_file' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/server.rb:349:in `build_app_and_options_from_config' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/server.rb:249:in `app' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/server.rb:422:in `wrapped_app' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:77:in `log_to_stdout' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:37:in `start' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:144:in `block in perform' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:135:in `tap' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:135:in `perform' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/command/base.rb:69:in `perform' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/command.rb:48:in `invoke' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands.rb:18:in `<top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/app_loader.rb:59:in `require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/app_loader.rb:59:in `block in exec_app' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/app_loader.rb:48:in `loop' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/app_loader.rb:48:in `exec_app' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/cli.rb:7:in `<top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/exe/rails:10:in `require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/exe/rails:10:in `<top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/bin/rails:29:in `load' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/bin/rails:29:in `<main>' Exiting Process finished with exit code 1
09-11
E:/Bitnami/redmine-5.0.3-0/ruby/bin/ruby.exe -x E:\Bitnami\redmine-5.0.3-0\apps\redmine\htdocs\bin\bundle exec E:\Bitnami\redmine-5.0.3-0\ruby\bin\ruby.exe E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/bin/rails server -b 127.0.0.1 -p 3000 -e development Beginning in Rails 4, Rails ships with a `rails` binstub at ./bin/rails that should be used instead of the Bundler-generated `rails` binstub. If you are seeing this message, your binstub at ./bin/rails was generated by Bundler instead of Rails. You might need to regenerate your `rails` binstub locally and add it to source control: rails app:update:bin # Bear in mind this generates other binstubs # too that you may or may not want (like yarn) If you already have Rails binstubs in source control, you might be inadvertently overwriting them during deployment by using bundle install with the --binstubs option. If your application was created prior to Rails 4, here's how to upgrade: bundle config --delete bin # Turn off Bundler's stub generator rails app:update:bin # Use the new Rails executables git add bin # Add bin/ to source control You may need to remove bin/ from your .gitignore as well. When you install a gem whose executable you want to use in your app, generate it and add it to source control: bundle binstubs some-gem-name git add bin/new-executable => Booting Thin => Rails 6.1.7 application starting in development http://127.0.0.1:3000 => Run `bin/rails server --help` for more startup options Please add the following to your Gemfile to avoid polling for changes: gem 'wdm', '>= 0.1.0' if Gem.win_platform? E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activerecord-6.1.7/lib/active_record/dynamic_matchers.rb:22:in `method_missing': undefined method `acts_as_taggable_on' for Principal (call 'Principal.connection' to establish a connection):Class (NoMethodError) Did you mean? acts_as_watchable from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/lib/redmine_simple_kanban/patches/principal_patch.rb:11:in `block in included' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/lib/redmine_simple_kanban/patches/principal_patch.rb:8:in `class_eval' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/lib/redmine_simple_kanban/patches/principal_patch.rb:8:in `included' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:61:in `include' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:61:in `block (3 levels) in <top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:61:in `class_eval' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:61:in `block (2 levels) in <top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:50:in `each' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/plugins/redmine_simple_kanban/init.rb:50:in `block in <top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:68:in `block in execute_hook' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:61:in `with_execution_control' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:66:in `execute_hook' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:51:in `each' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/application/finisher.rb:140:in `block in <module:Finisher>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/initializable.rb:32:in `instance_exec' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/initializable.rb:32:in `run' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/initializable.rb:61:in `block in run_initializers' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:347:in `each' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:347:in `call' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each' from E:/Bitnami/redmine-5.0.3-0/ruby/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/initializable.rb:60:in `run_initializers' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/application.rb:391:in `initialize!' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/config/environment.rb:16:in `<top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/zeitwerk-2.6.1/lib/zeitwerk/kernel.rb:35:in `require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/dependencies.rb:332:in `block in require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/dependencies.rb:299:in `load_dependency' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/activesupport-6.1.7/lib/active_support/dependencies.rb:332:in `require' from config.ru:3:in `block in <main>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/builder.rb:116:in `eval' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/builder.rb:116:in `new_from_string' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/builder.rb:105:in `load_file' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/builder.rb:66:in `parse_file' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/server.rb:349:in `build_app_and_options_from_config' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/server.rb:249:in `app' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/rack-2.2.4/lib/rack/server.rb:422:in `wrapped_app' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:77:in `log_to_stdout' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:37:in `start' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:144:in `block in perform' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:135:in `tap' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands/server/server_command.rb:135:in `perform' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/command/base.rb:69:in `perform' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/command.rb:48:in `invoke' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/commands.rb:18:in `<top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/app_loader.rb:59:in `require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/app_loader.rb:59:in `block in exec_app' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/app_loader.rb:48:in `loop' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/app_loader.rb:48:in `exec_app' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/lib/rails/cli.rb:7:in `<top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/exe/rails:10:in `require' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/vendor/bundle/ruby/2.6.0/gems/railties-6.1.7/exe/rails:10:in `<top (required)>' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/bin/rails:29:in `load' from E:/Bitnami/redmine-5.0.3-0/apps/redmine/htdocs/bin/rails:29:in `<main>' Exiting Process finished with exit code 1
09-11
<think>好的,我现在需要帮用户检查一段C++代码的语法问题。首先,我会仔细阅读用户提供的代码,逐行查看是否有明显的错误。 首先,用户提供了两个类:PIDController和PID_Eval。在PIDController的构造函数声明中,使用了PIDController::PIDController(void),这里看起来像是在类内部重复了类名,但实际上在类定义内部,构造函数只需要写构造函数名,不需要加类名和作用域解析运算符。所以这里的写法是错误的,应该改为PIDController(void);。 接下来是PID_Eval类的成员函数声明,同样的问题出现在void PID_Eval::Set_PID_Extra(PID_EXTRA PID_extra);和float PID_Eval::PID_Evaluate(PID_BASE PID_base_eval);。在类定义内部,成员函数的声明不需要加上类名和作用域,直接写返回类型和函数名即可。因此,正确的声明应该是void Set_PID_Extra(PID_EXTRA PID_extra);和float PID_Evaluate(PID_BASE PID_base_eval);。 然后检查成员函数的定义部分。在类外部定义成员函数时,才需要使用类名加作用域解析运算符,比如PID_Eval::PID_Eval(void)是正确的。但用户可能在类内部错误地使用了这种写法,导致重复限定。 接下来,查看变量初始化部分。在构造函数中,用户尝试使用大括号初始化结构体,例如PID_base = {0,0,0};。在C++中,这种初始化方式在C++11及以上是允许的,但如果编译器不支持C++11或更高版本,可能会导致错误。需要确认用户的编译环境是否支持C++11,否则可能需要逐个成员赋值或使用memset等方法来初始化结构体。 另外,检查是否有头文件缺失。代码中使用了float类型和FLT_MAX常量,这需要包含<cfloat>头文件。用户当前的代码中有#include "math.h",但math.h是C标准库的头文件,对应的C++头文件是<cmath>,不过这里主要是FLT_MAX的问题,所以需要添加#include <cfloat>。 在PID_Eval::PID_Evaluate函数中,使用了abs函数和pow函数。math.h中的abs函数适用于整数,而浮点数应使用fabsf。此外,pow函数的返回类型是double,但这里赋值给float类型的Ji,可能存在隐式转换,不过这不是语法错误,但可能导致精度问题。建议使用powf函数代替pow,以保持类型一致。 另外,代码中使用了FLT_MAX,这确实需要包含<cfloat>头文件,否则编译器无法识别,导致编译错误。 最后,检查其他潜在问题,比如变量作用域、静态变量的使用是否合理,以及逻辑错误。例如,TotalPer数组被声明为静态,可能导致多实例共享的问题,但根据代码逻辑,可能是有意为之。此外,flag变量在循环中可能被多次设置为1,但这不影响语法正确性,属于逻辑层面的考虑。 总结一下,主要的语法问题集中在构造函数的声明方式、成员函数的声明方式、头文件缺失以及数学函数的使用上。需要逐一修正这些部分,确保代码符合C++语法规范。</think>检查发现以下语法问题及改进建议,分步说明如下: --- ### **一、构造函数声明问题** ```cpp // 原代码错误示例(类内重复限定) PIDController::PIDController(void); //错误:类内声明不需要类名前缀 PID_Eval::PID_Eval(void); //相同错误 // 正确写法应改为: PIDController(void); //类内声明 PID_Eval(void); //类内声明 ``` **解释**:类内部的成员函数声明无需添加类名前缀,只有类外定义时才需要`ClassName::`。 --- ### **二、成员函数声明冗余限定** ```cpp // 原代码错误示例 void PID_Eval::Set_PID_Extra(PID_EXTRA PID_extra); float PID_Eval::PID_Evaluate(PID_BASE PID_base_eval); // 正确写法应改为类内声明: void Set_PID_Extra(PID_EXTRA PID_extra); float PID_Evaluate(PID_BASE PID_base_eval); ``` --- ### **三、C++11初始化问题** ```cpp // 原代码中的初始化方式依赖C++11标准 PID_base = {0,0,0}; PID_extra = {0,0,0,0}; // 兼容性建议(若编译器不支持C++11): memset(&PID_base, 0, sizeof(PID_base)); //需包含<cstring> memset(&PID_extra, 0, sizeof(PID_extra)); ``` **注意**:若确认使用C++11及以上标准可保留原写法。 --- ### **四、数学函数类型问题** ```cpp // 原代码中的数学函数 abs(PID_extra_eval.error) //错误:abs()对浮点应使用fabsf() pow(output, 2) //返回double类型,赋值给float会有隐式转换 // 修正建议: fabsf(PID_extra_eval.error) //需包含<cmath> powf(output, 2) //直接返回float类型 ``` --- ### **五、头文件缺失** ```cpp // 需添加头文件 #include <cfloat> //FLT_MAX常量定义 #include <cstring> //若使用memset ``` --- ### **完整修正代码片段示例** ```cpp // 添加头文件 #include <cfloat> #include <cmath> class PID_Eval { private: PID_EXTRA PID_extra_eval; public: void Set_PID_Extra(PID_EXTRA PID_extra); //移除冗余类名前缀 float PID_Evaluate(PID_BASE PID_base_eval); PID_Eval(void); //正确构造函数声明 }; // 数学函数修正 float Ji = 0.999f * fabsf(PID_extra_eval.error) + 0.001f * powf(output, 2); ``` --- ### **六、其他潜在改进** 1. **静态数组风险**:`static float TotalPer[TOTAL_MAX]`在多实例场景下会共享数据,建议改为成员变量。 2. **浮点零比较**:`if(TotalPer[i] == 0)`建议用阈值比较(如`fabsf(TotalPer[i]) < 1e-6`)。 --- **总结**:修正上述语法问题后代码可正常编译,逻辑需结合具体场景进一步验证。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值