barsoom / attr_extras Goto Github PK
View Code? Open in Web Editor NEWTakes some boilerplate out of Ruby with methods like attr_initialize.
License: MIT License
Takes some boilerplate out of Ruby with methods like attr_initialize.
License: MIT License
I often want to provide public attr_reader without implying value object semantics.
I have to use attr_initialize
followed by attr_reader
with the same list of attributes.
Would you be open to another shortcut like rattr_initialize
for public reader initialize?
Hi,
I love attr_extras, I use it everywhere, and chose it the tenth of alternative, great work guys.
Though I have case that I need reader, writer and initializer. sometimes private, public or protected.
So why not enabling something like:
attr_accessor_initialize :foo, :goo
Instead of this:
attr_initialize :foo, :goo
attr_accessor :foo, :goo
or this:
attr_reader_initialize :foo, :goo
attr_writer :foo, :goo
Like https://github.com/tonsser/takes_macro.
Consider:
We want good backtraces: https://stackoverflow.com/questions/2496102/what-does-class-eval-end-eval-file-line-mean-in-ruby See it used in Traco: https://github.com/barsoom/traco/blob/f0632591f26f762f73766999080a793dba98e6b4/lib/traco/attributes.rb#L24
Security implications. Any risk of end-user-provided data not being properly escaped, causing vulnerabilities?
Benchmark it (see takes_macro
).
Hi! ๐
Thank you for creating this library, I've been using it for over a year on most of the stuff I do and it has been great! (99% of time basically using the method object).
I've wanted to ask you, is there an option to pass default values to keyword arguments on method objects?
Seeings the likes of:
...gems/2.7.0/gems/attr_extras-6.2.3/lib/attr_extras/explicit.rb:66: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
Any idea if there's a way around it, or how to fix?
Hi,
Is it possible to initialize custom instance variables in addition to using pattr_initialize ?
For example: @time = Time.now
Thanks
Hello.
I'm not familiar with this library (I only scanned the README) but I think you might be interested in the fact, that as of Ruby 3.0, it supports chaining private
call with methods that defines attribute accessors (I implemented this, see https://bugs.ruby-lang.org/issues/17314). Having this feature, it is unnecessary to have method like attr_private
and I think it would be good idea to mention that in the README file.
Here is example usage.
class Foo
private attr_accessor :foo, :bar
# this the same as:
attr_accessor :foo, :bar
private :foo, :foo=, :bar, :bar=
end
This works with any method which returns defined method name (symbol) or defined method names (array of symbols). As of Ruby 3.0 attr_{reader,writer,accessor}
returns array of defined method names:
class Foo
p attr_accessor :foo, :bar #=> [:foo, :foo=, :bar, :bar=]
end
require "attr_extras"
class Foo < BasicObject
pattr_initialize :bar
def hello
bar
end
end
Foo.new("bar-value").hello
undefined method `instance_variable_set' for #<Foo:0x007f7bace49a38> (NoMethodError)
In the document, it says: attr_initialize
can also accept a block which will be invoked after initialization. This is useful for calling super
appropriately in subclasses or initializing private data as necessary.
But there isn't an example for this case, when I want to call super
in attr_initialize
, I don't know how to make it working.
class MyBaseClass
def initialize
puts 'I am base class'
end
end
class MyClass < MyBaseClass
attr_initialize :foo do
super
end
end
MyClass.new('foo') # => NoMethodError: super called outside of method
Do I use it incorrectly? I am using Ruby 2.0.0p353
I think it would be less cryptic to rename pattr_initialize
to prattr_initialize
to indicate that it is a private reader that's being created, and not just use the 'p' from private.
For someone who doesn't have a lot of experience using this gem or a lack of development experience in general, I think this simple change could make it easier to understand what exactly is going on when you use this method.
To stop this from breaking a lot of stuff, you could just add this in as an alias for now ๐
Some companies will only use gems with a certain license.
The canonical and easy way to check is via the gemspec
via e.g.
spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']
There is even a License Finder to help companies ensure all gems they use
meet their licensing needs. This tool depends on license information being available in the gemspec.
Including a license in your gemspec is a good practice, in any case.
How did I find you?
I'm using a script to collect stats on gems, originally looking for download data, but decided to collect licenses too,
and make issues for missing ones as a public service :)
https://gist.github.com/bf4/5952053#file-license_issue-rb-L13 So far it's going pretty well
Hello ๐
thank you for creating this library. I really enjoy to use it.
I've faced with the bug that pattr_initialize
(as well as vattr_initialize
and rattr_initialize
methods) doesn't support default values for keyword arguments which were described in the attr_initialize
notation for keyword arguments. I can check it in the Rails console
> class Test
> pattr_initialize [value: true]
> end
NameError: invalid attribute name `{:value=>true}'
...
BTW, when I'm using attr_initialize
and att_private
separately, it works correctly
> class Test
> attr_initialize [value: true]
> attr_private :value
>
* def test
> value.to_s
> end
> end
=> :test
> Test.new.test
=> "true"
> Test.new(value: 1).test
=> "1"
It would be nice to keep RubyGems releases and git tags in sync :)
Hey,
Is there a reason why only keyword arguments can have default values?
Syntax like:
class Make
attr_initialize :target, params: {}
end
would take even more boilerplate out of peoples codebases IMO.
I'm implementing a builder pattern that has lots of code like:
def id(id)
@id = id
self
end
def container_type(container_type)
@container_type = container_type
self
end
def store(store)
@store = store
self
end
A attr_fluent_writer
or something that covers this case would be handy to have here.
minitest-5.14.1 requires ruby version ~> 2.2, which is incompatible with the current version, ruby 3.0.0p0
Using the latest version attr_extras (6.2.5)
, if you define a default value in an initializer that is an array value (i.e. []
), each instance of the class shares the same value of that array.
I thought these were roughly equivalent in function, but the results are not what I expected. This is a simplified example of what I am getting in our current implementation.
class Foo
aattr_initialize [:name, items: []]
end
data = [
{ name: "One", items: [1, 2, 3] },
{ name: "Two", items: [4, 5, 6] },
]
data.each_with_object([]) do |datum, results|
name, items = datum.values_at(:name, :items)
foo = Foo.new(name: name)
items.each do |n|
foo.items << n
end
results << foo
end
=> [#<Foo @items=[1, 2, 3, 4, 5, 6], @name="One">, #<Foo @items=[1, 2, 3, 4, 5, 6], @name="Two">]
class Bar
attr_accessor :name, :items
def initialize(name:, items: [])
@name = name
@items = items
end
end
data = [
{ name: "One", items: [1, 2, 3] },
{ name: "Two", items: [4, 5, 6] },
]
data.each_with_object([]) do |datum, results|
name, items = datum.values_at(:name, :items)
bar = Bar.new(name: name)
items.each do |n|
bar.items << n
end
results << bar
end
=> [#<Bar @items=[1, 2, 3], @name="One">, #<Bar @items=[4, 5, 6], @name="Two">]
If I initialize the object with an empty array it is fine.
foo = Foo.new(name: name)
# vs
foo = Foo.new(name: name, items: [])
class Foo
aattr_initialize [:name, items: []]
end
data = [
{ name: "One", items: [1, 2, 3] },
{ name: "Two", items: [4, 5, 6] },
]
data.each_with_object([]) do |datum, results|
name, items = datum.values_at(:name, :items)
foo = Foo.new(name: name, items: [])
items.each do |n|
foo.items << n
end
results << foo
end
=> [#<Foo @items=[1, 2, 3], @name="One">, #<Foo @items=[4, 5, 6], @name="Two">]
I didn't have time to dig in yet, but wanted to get this submitted to see if this is unexpected or if I just misunderstood the implementation.
I get this:
gems/attr_extras-6.1.0/lib/attr_extras/attr_initialize.rb:36:in `instance_variable_set': `@hammer_absentee_max_bid.minimum_amount' is not allowed as an instance variable name (NameError)
Plan on looking at it after this lunch break :) Also to track down what in our code causes it exactly.
One idea for fix would be to not use ivars directly but instead a hash, e.g. set @foo["hammer_absentee_max_bid.minimum_amount"]
.
cc @lesin
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.