Rails 4, get all locals in partial - partial-views

How to get all locals as a hash in a partial view.
# mainview.html.haml:
= render 'v1', p1: 100, p2: 'some_value', _other_values_
in a partial view:
# _v1.html.haml
# do something here...
# render another partial view
= render 'another_view', locals: locals # what to write here???
How to access ALL variables in locals as a hash.
I don't want to list all variables in locals.

Use local_assigns.
local_assigns #=> { p1: 100, p2: 'some_value', _other_values_ }
_v1.html.haml
= render 'another_view', local_assigns

Related

Coffeescript - reassign upper-scope variable using a function

fun=->
views = []
views = 123
fun()
console.log views
Which compiles to
var fun, views;
fun = function() {
var views;
return views = [];
};
views = 123;
fun();
console.log(views);
And logs 123 whereas I want it to return [].
Declaring views before fun would produce required result, but my code style requires that I first declare all functions and then assign variables.
What can be done in this case? Particularly I want coffeescript to not produce var views; in javascript inside fun.
Another possibility - while a bit more compex - would be to use a class and bind the function and the fun function to the class scope.
class muchFun
views: 123
fun: =>
#views = []
return
soMuchFun = new muchFun()
console.log( soMuchFun.views )
soMuchFun.fun()
console.log( soMuchFun.views )
If you want fun to know about the outer views then you have to define views before fun:
views = 123
fun = ->
views = []

How should I document singletons?

I'm not sure which tag I should use to document singletons like the following:
var singleton = {
c: 1,
f: function(){
return this.c;
}
}
When I use #namespace the member function f will be declared as <static>, and I'ts not a namespace anyway. But it's obviously neither a #class. Is there a separate tag or trick you use for singletons?

CoffeeScript: access actual #(this) in fat arrow function => [duplicate]

The title says it all. When I use the fat-arrow in CoffeeScript, it stores this first before calling the function. For example:
class myClass
constructor: ->
element = $ "#id"
element.click ->
#myMethod(#value)
return
return
myMethod: (c)->
window.console.log(c)
return
would yield
var myClass;
myClass = (function() {
function myClass() {
var element;
element = $("#id");
element.click(function() {
this.myMethod(this.value);
});
return;
}
myClass.prototype.myMethod = function(c) {
window.console.log(c);
};
return myClass;
})();
Now on line#8 of JavaScript, this.myMethod is wrong. In this scope, this refers to element instead of the class MyClass.
However, if on line#4 of CoffeeScript, I replace element.click -> by element.click => the line#8 in JavaScript will become _this.myMethod(_this.val) where this referring to myClass is stored in _this before calling the function. But _this.value is undefined and even if it were defined, the object I'm trying to access here is element (which is referred to by the actual this keyword in scope of this function).
How would access the actual this now?
You can achieve your goal in at least three ways. The 1st one would be:
class myClass
constructor: ->
element = $ "#id"
element.click =>
#myMethod(element.value)
return
return
myMethod: (c) ->
window.console.log(c)
return
And the 2nd:
class myClass
constructor: ->
element = $ "#id"
myMethodCallback = (c) => #myMethod(c)
element.click ->
myMethodCallback(#value)
return
return
myMethod: (c) ->
window.console.log(c)
return
The 3rd one is as showed below. I'm not sure about jQuery API usage though, so better check on appropriate docs page.
class myClass
constructor: ->
element = $ "#id"
element.click (event) =>
#myMethod(event.target.value)
return
return
myMethod: (c) ->
window.console.log(c)
return
I would prefer the 1st way as it seems to be more straightforward.
This or the other but you need to decide 'which this' you would like to have in scope of the element.click callback. It's not possible to access two 'thises' at the same time.
By the way. All those return statements seems unnecessary. The shortest working solution would look like:
class myClass
constructor: ->
element = $ "#id"
element.click => #myMethod(element.value)
myMethod: (c) -> window.console.log(c)

How to make Data::Printer show stringified values in internals?

I have some complex object structures, and I use Data::Printer to inspect them. One case where it's not helpful enough is this: when an object (container) has a field that's another object (child), the child shows up in DDP's output only as class name. I wish to also see the stringified value of the child.
Let's have an example:
{
package Child;
use Moo;
use overload '""' => "stringify";
has 'value', is => 'ro';
sub stringify {
my $self = shift;
return "<Child:" . $self->value . ">";
}
}
{
package Container;
use Moo;
has 'child', is => 'ro';
}
my $child_x = Child->new(value => 'x');
print "stringified child x: $child_x\n";
my $child_y = Child->new(value => 'y');
print "stringified child y: $child_y\n";
my $container_x = Container->new(child => $child_x);
my $container_y = Container->new(child => $child_y);
use DDP;
print "ddp x: " . p($container_x) . "\n";
print "ddp y: " . p($container_y) . "\n";
Output:
stringified child x: <Child:x>
stringified child y: <Child:y>
ddp x: Container {
Parents Moo::Object
public methods (2) : child, new
private methods (0)
internals: {
child Child # <- note this
}
}
ddp y: Container {
Parents Moo::Object
public methods (2) : child, new
private methods (0)
internals: {
child Child # <- and this
}
}
As you see, the children are indistinguishable in the output. I'd like to see the stringification in that place, either in addition to or instead of the class name.
Per the Data::Printer docs,
Data::Printer offers you the ability to use filters to override any
kind of data display. The filters are placed on a hash, where keys are
the types - or class names - and values are anonymous subs that
receive two arguments: the item itself as first parameter, and the
properties hashref (in case your filter wants to read from it). This
lets you quickly override the way Data::Printer handles and displays
data types and, in particular, objects.
As Dave pointed out, we can define the filter when importing Data::Printer:
use DDP filters => {
'Child' => sub { "$_[0]" }
};
And even better way would be to use the _data_printer feature (because it's a pain to type out the filters definition every time I import DDP):
{
package Child;
...
sub _data_printer {
my $self = shift;
return "$self";
}
}
Both ways display the stringified value in internals:
ddp x: Container {
Parents Moo::Object
public methods (2) : child, new
private methods (0)
internals: {
child <Child:x>
}
}

Modifying a variable class attribute

I'm trying to modify a class attribute based on the argument given. I'm just getting into python but I can't seem to find a way to do it without using a dictionary. Is there a pythonic way to do this? See example below
class Ship:
def __init__(self, name):
self.name = name
ship_type = {"schooner": [50, 30, 18],
"galleon": [30, 14, 14]
}
self.max_weight = ship_type[name][0]
self.speed = ship_type[name][1]
self.poopdeck = ship_type[name][2]
def upgrade(self, attribute, value):
self.attribute += value
Someship.ship.upgrade(speed, 10)
I can write out a different method for each attribute but I feel as if there has to be something like this.
I apologize in advance if this has already been answered but I couldn't word it right if there is.
Change the update method to update an existing attribute by using the builtin functions hasattr(), setattr() and getattr().
def upgrade(self, attribute, value):
if hasattr(self, attribute):
setattr(self, attribute, getattr(self, attribute) + value )
else:
raise AttributeError("Can't upgrade non-existent attribute '{}'.".format(attribute))
Note that I'd also use the __dict__ attribute to make setting up your instances easier:
class Ship:
# types is a class variable, and will be the same for all instances,
# and can be referred to by using the class. ie `Ship.types`
types = {
"schooner": {'weight':50, 'speed':30, 'poopdeck':18},
"galleon": {'weight':30, 'speed':14, 'poopdeck':14},
"default": {'weight':11, 'speed':11, 'poopdeck':11}
}
def __init__(self, name):
self.name = name
# we update the instance dictionary with values from the class description of ships
# this means that instance.speed will now be set, for example.
if name in Ship.types:
self.__dict__.update(Ship.types[name])
else:
self.__dict__.update(Ship.types["default"])
def upgrade(self, attribute, value):
if hasattr(self, attribute):
setattr(self, attribute, getattr(self, attribute) + value )
else:
raise AttributeError("Can't upgrade non-existent attribute '{}'.".format(attribute))
ship = Ship("schooner")
print(ship.speed) #=> 30
ship.upgrade("speed", 10)
print(ship.speed) #=> 40
You are looking for the setattr and getattr functions. Your upgrade method can be implemented as
def upgrade(self, attribute, value):
setattr(self, attribute, getattr(self, attribute) + value )