The Original Problem
Changed ruby version (1.9.3 > 1.9.2) and suddenly all coffeescripts started yielding unexpected INDENT.
I've triple-checked for spaces/tabs inconsistency on files, and this is not the issue. When I comment the entire script, the same bug jumps to the next/another coffeescript file.
Tried with coffee-rails versions 3.2.1 and 3.2.2. No success in both.
Anyone to light a lamp?
More Details
I found what causing this, yet I can't understand why it shoud work differently for different Ruby versions. It's a long story, but here it goes.
I use a trick to declare static or dynamic getters and setters to my classes. This is something like:
Function::dynamic = (prop, desc) ->
Object.defineProperty #prototype, prop, desc
Function::static = (prop, desc) ->
Object.defineProperty #, prop, desc
This provides me a way to declare properties like this:
class MyClass
#static 'accessor'
get: -> _accessor
set: (value) -> _acessor = value
I have plenty of this all over my code, but after Ruby downgrade the code structure just stopped working. Now I'll have to add a comma after the method's first parameter. Like:
#static 'accessor',
get: -> (...)
And this is what it was all about. :S
Answer its not longer necessary, but if anyone could explain it... I'd be glad.
This syntax was not allowed "on purpose", if was merely allowed because the compiler refused to generate 'a'(...). ID block is a call
See this issue.
Related
I am new to rails world. In one of the existing rails project I am working, I see a line in a model class as mentioned below. Can someone please tell me what does this signify. I tried searching documentation but couldn't find "kept" keyword anywhere.
default_scope -> { kept }
From what I get, this is a scope that might be provided by a gem that allows you to "discard" records (instead of deleting them). The default scope is set to only return results that are kept (i. e. not discarded). Of course the functionality could also be developed manually but then you'd find the code in your project (e. g. in the model or a concern).
A popular gem to achieve this would be https://github.com/jhawthorn/discard (not affiliated with it) which effectively uses kept. Maybe check your Gemfile what gems your project uses and search their docs for this.
I would expect that application of sort_by would change the order, but nothing else, about an array.
Here's my original line:
gon.frames = #job.sequence.frames.sort_by(&:n)
And a modified line, where sort_by is removed:
gon.frames = #job.sequence.frames
I'm finding that the values in gon.frames (which is transmitted to the browser using the gon gem) are different, not just in order, but in how they are converted to strings.
This issue seemed to appear after upgrading to ruby 3.0.0.
Edit: inspecting with Rails console shows that the first line is returning type Array, whereas the second line is returning type ActiveRecord::Associations::CollectionProxy.
I am still confused, because this didn't seem to be happening prior to my recent upgrades and change to ruby 3.0.0.
Edit - not sure what the root cause is here, but I rolled back to ruby 2.6.1 and the problem went away.
Edit - I think the change that I experienced may not be related to the type of frames. Instead, it could be that gon is doing something differently in how it passes this variable to the browser when ruby 3.0.0 is used.
I wrote a lib/animal.rb with several lists of params, and I want to reference that list in my controller and add it my params list. I did this because I use this list in several locations and didn't want to litter my code with a bunch of references to the library.
Controller
ANIMAL_TYPE_INPUT_PARAMS = *Animals::ANIMAL_TYPE_PARAMS.freeze
....
def familar_params
params.permit(ANIMAL_TYPE_INPUT_PARAMS, OTHER_PARAM_LIST....)
end
Lib/animal.rb
module Animal
# param lists
ANIMAL_TYPE_PARAMS = [
:animal_has_fur, :animal_id, :animal_weight
].freeze
end
Functionally it works just fine, but I am seeing a weird rubocop error. I would prefer to not disable MutableConstant for this section (disabling rubocop is usually a band aid that you pay for at some point).
Rubocop error
app/controllers/api/v1/example_controller.rb:55:24: C: Freeze mutable objects assigned to constants.
ANIMAL_TYPE_INPUT_PARAMS = *Animals::ANIMAL_TYPE_PARAMS.freeze
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I looked into this question: Ruby rubocop: how to freeze an array constant generated with splat But mine are already arrays, so I feel like it doesn't apply to me / shouldn't have to call to_a.
As #drenmi suggested, it was an older version of rubocop giving me this error. Once I upgraded to 0.46.0 the error was no longer.
I don't know why these two pieces of code behave different in Ruby 1.8.7 since one seems to be the single line version of the other.
The first piece of code (it works as it should):
if #type.present?
type = #type
orders = Order.where{type.eq(type)}
end
The single line version (it doesn't work at all, no error but seems no execution too):
orders = Order.where{type.eq(type)} if (type = #type).present?
NOTE: I'm using the squeel gem, that is the reason a block follows the where method. Also the variable type has to capture the instance variable #type since the execution context changes inside the block and the instance variables are not shared between the main context and the block context.
NOTE 2: I have to use Ruby 1.8.7 for legacy reasons.
Any idea? Thank you!
There is a problem with the order of parsing of your code. Variables need to be defined before they are used.
Even though variables defined inside if statement clauses "leak" out into the current scope, they do not leak "backwards" in Ruby code.
Ruby is a little bit curious in that way that variables need to be defined before the parser parses the code. The parsing is done from top to bottom and left to right.
Hence since the variable type is defined after your block code where you use it, it will not be available in the block.
Example:
>> 3.times { puts x } if (x = 123)
NameError: undefined local variable or method `x' for main:Object
The reason you don't get any error message is that in Ruby 1.8 type is a method that is a synonym for Object#class.
So what your code is really doing is (probably):
orders = Order.where{type.eq(this.class)} if (type = #type).present?
To fix it you have to define type before you use it. Therefore you can't really turn that into a one-liner unless you simply do this instead:
orders = Order.where{type.eq(#type)} if #type.present?
All in all it's not a good idea in Ruby 1.8 to use type as a variable in Rails models, because of the Object#class issue it will most likely bring you headaches in the long run.
similar problem that i got was that 'type' is a keyword in database, it allows for our model to have the field as 'type' but it works strangely in different conditions. if changing the name is an option for you then check after changing it, worked for me...
gem Squeel uses instance_eval method when calls block which passed to where. So, there is no any #type in squeel instance. If you want to use methods or variables from another context, try to wrap it into method my with block
orders = Order.where { type.eq my { #type } } if #type.present?
PS sorry for my English
I been working on porting my application on "Rails 3.0.7" ,ever since I started to employ caching for my application either (file cache,memcache or any other) . I always happen to get the above error "can't dump File" .
I Google a bit and found that it has something to do with Marshal dump as ruby interpreter does allow Marshal dump of object that have Procs or lambdas in them so I looked upon my code but I could not find any Proc and lambda in my whole applications
Now to discover the problem I drill down the ActiveRecord 3.0.7 code and here are few interesting finding that I came up with
1 . "includes" in Rails 3 + internally call the define name scope OK this I give the answer that there is Proc and Lambada associated with the object so the error but this doesn't explain why the same code work sometime and report with errors(above errors) other times I mean If the error is for the Marshalling and object that hold a Proc or a Lambada then code should definitely not work and should always report errors no matter how many times the same code is ran but that not the case over here the code return errors sometimes and work well other times
Code
Rails.cache.fetch("accessible_websites_1")
{ Website.includes(:account) }
2 . If the ".includes" in Rails 3.0 + has problem then what up with other 'include' syntax does it too report error (above error)
so I ran the code with older syntax of include
Here is it
Rails.cache.fetch("accessible_websites_1")
{ Website.all(:include =>
:account) }
well surprisingly it ran but it never preloaded the account related for all the website ( which is where weird) but at least It never gave and error
so did a forensic on Active Record 3.0 + once again to discover how the older version of include(Rails 2.3 +) work surprise to know that the older version of include syntax internally call the .includes method of ActiveRecord 3.0 +
whoo How is that possible
two different syntax both call the same internal method one report with error sometimes ( not every time but preload the associated object) and other does not report with error but neither preload the associated object as said earlier.
OK , Hearing all this if anyone can help me out then I would be utmost grateful
By the way
Here what I'm trying to achieve
Rails.cache.fetch("accessible_websites_1")
{ Website.includes(:account) }
the equivalent code of above in Rails 2.3.5 and Rails 3 + (but does not preload the associated account object of all websites)
i.e
Rails.cache.fetch("accessible_websites_1")
{ Website.find(:all,:include =>
:account) }
Work perfectly fine without any issue
I using
Ruby = "ruby 1.8.7 (2010-01-10
patchlevel 249) [i486-linux]" Rails
= " Rails 3.0.7"
The same Problem even persisted on Rails 3.1.0
am I missing something
I can also provide the model structure if required
The problem is that
Website.includes(:account)
does not load the data, it just provides you with a proxy object that will load the objects on demand when you do something like calling #each or #to_s, if you force the fetching by adding a #to_aat the end it should work, e.g. try
Marshal.dump(Website.includes(:account))
Marshal.dump(Website.includes(:account).to_a)
#all(x=>y) does not do the same thing as #x(y), that is why you can do X.includes.joins.where but not X.all.where.
Not sure where the reference to a File comes from though.