On call of attribute_foo=(bar), call custom code, to change bar - ruby-on-rails-3

For some reason, a simple piece of decorator-code fails on my production machine, but runs fine on development[1].
I dumbed it down, and found that the following is the simplest failing piece:
Spree::Variant.class_eval do
def price=(value)
self.price = normalize_number(value)
end
end
Failing with SystemStackError (stack level too deep):
Debugging shows me that, indeed, the function keeps being called. self.price= calls price=.
What is a usual Rails/Ruby pattern to tackle this? What I want is:
When attribute_foo=(bar) gets called, delegate it to my custom code, where I can run the passed bar trough a small piece of custom code. Then assign that altered bar to attribute_foo.
[1]:
The only difference is the Ruby patch version and the fact that the production machine has 64-bit version, versus 32bit-version on dev: ruby 1.8.7 (2011-02-18 patchlevel 334) [x86_64-linux].

The solition was simple: just use write_attribute.
Spree::Variant.class_eval do
def price=(value)
write_attribute(:price, bar(value))
end
end

Related

How to show “Intra-package call graph” using “godoc”

How can I show “Intra-package call graph” using godoc as described in Intra-package call graph ?
I use this command
$ GO111MODULE=off godoc -http=:6060 -analysis=type,pointer
to start a local server and everything is fine. I just cannot find where the “Intra-package call graph” is.
Any help is appreciated!
Solved.
It just takes too long to do "Pointer analysis", which is approximately 4.5 minutes on my laptop. The "Intra-package call graph" for hole package and every function appeared until "2021/03/16 15:04:28 Pointer analysis running..." had disappeared from my terminal.
And "-analysis=pointer" is just efficient.

Cucumber - perform ActiveJob `perform_later` jobs immediately

I have many jobs that are calling other nested jobs using perform_later. However, during some tests on Cucumber, I'd like to execute those jobs immediately after to proceed with the rests of the tests.
I thought it would be enough to add
# features/support/active_job.rb
World(ActiveJob::TestHelper)
And to call jobs using this in a step definition file
perform_enqueued_jobs do
# call step that calls MyJob.perform_later(*args)
end
However I run into something like that
undefined method `perform_enqueued_jobs' for #<ActiveJob::QueueAdapters::AsyncAdapter:0x007f98fd03b900> (NoMethodError)
What am I missing / doing wrong ?
I switched to the :test adapter in tests and it worked out for me:
# initialisers/test.rb
config.active_job.queue_adapter = :test
# features/support/env.rb
World(ActiveJob::TestHelper)
It would seem as long as you call .perform_now inside the cucumber step, even if there are nested jobs with .deliver_later inside, it does work too
#support/active_job.rb
World(ActiveJob::TestHelper)
#my_job_steps.rb
Given(/^my job starts$/) do
MyJob.perform_now(logger: 'stdout')
end
#jobs/my_job.rb
...
MyNestedJob.perform_later(*args) # is triggered during the step
...
Also, in my environment/test.rb file I didn't write anything concerning ActiveJob, the default was working fine. I believe the default adapter for tests is :inline so calling .deliver_later _now shouldn't matter

Web application could not be started

I trying to use apache2 and mod passenger to run my rails application.
My setup is working fine when i use ubuntu 12.04.
Now i have updated to 14.04 and trying to get my application running.
but i always get the following long error.
/home/sandeep/.rvm/gems/ruby-2.1.1/gems/json-1.8.1/lib/json/common.rb:67: [BUG]
Segmentation fault
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0057 p:---- s:0163 b:0163 l:000162 d:000162 CFUNC :initialize
c:0056 p:---- s:0161 b:0161 l:000160 d:000160 CFUNC :new
c:0055 p:0099 s:0158 b:0156 l:000155 d:000155 METHOD /home/sandeep/.rvm/gems/ruby- 2.1.1/gems/json-1.8.1/lib/json/common.rb:67
c:0054 p:0090 s:0147 b:0146 l:000145 d:000145 CLASS /home/sandeep/.rvm/gems/ruby- 2.1.1/gems/json-1.8.1/lib/json/ext.rb:17
c:0053 p:0011 s:0144 b:0144 l:000143 d:000143 CLASS /home/sandeep/.rvm/gems/ruby-2.1.1/gems/json-1.8.1/lib/json/ext.rb:12
c:0052 p:0074 s:0142 b:0142 l:000141 d:000141 TOP /home/sandeep/.rvm/gems/ruby-2.1.1/gems/json-1.8.1/lib/json/ext.rb:9
c:0051 p:---- s:0140 b:0140 l:000139 d:000139 FINISH
....
I cannot pin point exactly where the problem is with information you have given, however there is a guide on how to reinstall ruby, check if you are doing something different.

How to tell whether elaboration has completed at a breakpoint?

When I hit a breakpoint in a VLAB script, how can I find out if I have caused elaboration to finish or not, yet?
My script reaches a statement that raises an error:
Error: (E529) insert module failed: elaboration done
(The command that causes this is vlab.instantiate("stim", "stim"))
So obviously elaboration was unexpectedly (for me) already completed. I need to somehow go back in the process and find out where that happened - so I need some way of asking "is elaboration complete?" at the point where I set breakpoints earlier in the script.
SystemC provides the following function to query the current phase of elaboration or simulation.
sc_status sc_get_status();
It returns either SC_ELABORATION, SC_BEFORE_END_OF_ELABORATION, SC_END_OF_ELABORATION, SC_START_OF_SIMULATION, SC_RUNNING, SC_PAUSED, SC_STOPPED, or SC_END_OF_SIMULATION.
See section 4.5.8 in the SystemC Language Reference Manual for more details. Note that this function was only added in the most recent version of the standard, IEEE Standard 1666-2011.
In VLAB, the SystemC API is available from the sysc Python package, so the following script can be used to test if the current phase is at elaboration:
import sysc
print "Is elaboration phase:", sysc.sc_get_status() == sysc.SC_ELABORATION

Getting a list of existing Rails Error classes for re-use/inheritance

Often I need to throw a custom(ized) error. Like when a resource cannot be found due to a mismatch in parameters or so.
I prefer to throw existing errors or, throw an error that is inherited from an existing error. That way, I don't introduce Error classes that were already defined and could have been used perfectly (DRY). But it also allows to keep wording and style the same, by inheriting and simply changing a word or two to clarify the difference with the original Error.
For example:
Foo.new
Foo.some_external_id = nil
Foo.fetch_external_resource
# => InvalidOptions: Calling Foo#fetch_external_resource with nil is invalid
I am quite sure such errors are already defined. In fact, after reading trough many lines of code, I found my MongoID driver has Mongoid::Errors::InvalidOptions: Calling Document#find with nil is invalid.
Is there a list of available Error classes in Ruby Core and Ruby on Rails? Is there a way to get such a list for your current project?
Is it smart at all to re-use and/or inherit existing errors, or should I maintain my own, custom set instead?
While this list may change, and it's best to still use Ryan's solution, the list for Rails 4 (limited to Rails classes and not other gems):
AbstractController::ActionNotFound
AbstractController::DoubleRenderError
AbstractController::Error
AbstractController::Helpers::ClassMethods::MissingHelperError
ActionController::ActionControllerError
ActionController::BadRequest
ActionController::InvalidAuthenticityToken
ActionController::MethodNotAllowed
ActionController::MissingFile
ActionController::NotImplemented
ActionController::ParameterMissing
ActionController::RedirectBackError
ActionController::RenderError
ActionController::RoutingError
ActionController::SessionOverflowError
ActionController::UnknownController
ActionController::UnknownFormat
ActionController::UnknownHttpMethod
ActionController::UnpermittedParameters
ActionController::UrlGenerationError
ActionDispatch::Cookies::CookieOverflow
ActionDispatch::IllegalStateError
ActionDispatch::Journey::Router::RoutingError
ActionDispatch::ParamsParser::ParseError
ActionDispatch::RemoteIp::IpSpoofAttackError
ActionDispatch::Session::SessionRestoreError
ActionView::Helpers::NumberHelper::InvalidNumberError
ActiveModel::ForbiddenAttributesError
ActiveModel::MissingAttributeError
ActiveRecord::ActiveRecordError
ActiveRecord::AdapterNotFound
ActiveRecord::AdapterNotSpecified
ActiveRecord::AssociationTypeMismatch
ActiveRecord::AttributeAssignmentError
ActiveRecord::ConfigurationError
ActiveRecord::ConnectionNotEstablished
ActiveRecord::ConnectionTimeoutError
ActiveRecord::DangerousAttributeError
ActiveRecord::DeleteRestrictionError
ActiveRecord::DuplicateMigrationNameError
ActiveRecord::DuplicateMigrationVersionError
ActiveRecord::EagerLoadPolymorphicError
ActiveRecord::HasAndBelongsToManyAssociationForeignKeyNeeded
ActiveRecord::HasManyThroughAssociationNotFoundError
ActiveRecord::HasManyThroughAssociationPointlessSourceTypeError
ActiveRecord::HasManyThroughAssociationPolymorphicSourceError
ActiveRecord::HasManyThroughAssociationPolymorphicThroughError
ActiveRecord::HasManyThroughCantAssociateNewRecords
ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection
ActiveRecord::HasManyThroughCantDissociateNewRecords
ActiveRecord::HasManyThroughNestedAssociationsAreReadonly
ActiveRecord::HasManyThroughSourceAssociationNotFoundError
ActiveRecord::HasOneThroughCantAssociateThroughCollection
ActiveRecord::IllegalMigrationNameError
ActiveRecord::ImmutableRelation
ActiveRecord::InvalidForeignKey
ActiveRecord::InverseOfAssociationNotFoundError
ActiveRecord::IrreversibleMigration
ActiveRecord::MultiparameterAssignmentErrors
ActiveRecord::NestedAttributes::TooManyRecords
ActiveRecord::PendingMigrationError
ActiveRecord::PreparedStatementInvalid
ActiveRecord::ReadOnlyAssociation
ActiveRecord::ReadOnlyRecord
ActiveRecord::RecordInvalid
ActiveRecord::RecordNotDestroyed
ActiveRecord::RecordNotFound
ActiveRecord::RecordNotSaved
ActiveRecord::RecordNotUnique
ActiveRecord::Rollback
ActiveRecord::SerializationTypeMismatch
ActiveRecord::StaleObjectError
ActiveRecord::StatementInvalid
ActiveRecord::SubclassNotFound
ActiveRecord::Tasks::DatabaseAlreadyExists
ActiveRecord::Tasks::DatabaseNotSupported
ActiveRecord::ThrowResult
ActiveRecord::TransactionIsolationError
ActiveRecord::Transactions::TransactionError
ActiveRecord::UnknownAttributeError
ActiveRecord::UnknownMigrationVersionError
ActiveRecord::UnknownPrimaryKey
ActiveRecord::WrappedDatabaseException
ActiveSupport::JSON::Encoding::CircularReferenceError
ActiveSupport::MessageVerifier::InvalidSignature
ActiveSupport::SafeBuffer::SafeConcatError
ActiveSupport::XMLConverter::DisallowedType
There's a mostly adequate solution here: http://www.ruby-forum.com/topic/158088
Since this question is unanswered, yet coming up at the top of Google search results, I decided to wrap Frederick Cheung's solution up in a rake task and post it here.
Drop the following in lib/tasks/exceptions.rake
namespace :exceptions do
task :list => :environment do
exceptions = []
ObjectSpace.each_object(Class) do |k|
exceptions << k if k.ancestors.include?(Exception)
end
puts exceptions.sort { |a,b| a.to_s <=> b.to_s }.join("\n")
end
end
Run it with:
bundle exec rake exceptions:list
If you're still on Rails 2, or not using Bundler, leave off the bundle exec
This list is probably adequate, but not exhaustive. For example, ActiveResource defines several exceptions such as ActiveResource::ConnectionError and ActiveResource::TimeoutError that are not appearing when I run this task. Maybe someone else can enlighten me as to why.
A shorter option is available in Rails thanks to ActiveSupport:
puts Exception.descendants.sort_by(&:name)
You can also check out the source to see how they handle it.