标签: metaprogramming

define_method:如何使用参数动态创建方法

我想为find_by功能创建一堆方法.我不想一遍又一遍地写同样的东西所以我想使用元编程.

假设我想创建一个按名称查找的方法,接受名称作为参数.我该怎么办?我以前使用过define_method但是我没有任何关于该方法的参数.这是我的(坏)方法

["name", "brand"].each do |attribute|
    define_method("self.find_by_#{attribute}") do |attr_|
      all.each do |prod|
        return prod if prod.attr_ == attr_
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

有什么想法吗?提前致谢.

ruby metaprogramming

31
推荐指数
2
解决办法
2万
查看次数

有没有办法做一个C++样式的编译时断言来确定机器的字节序?

我有一些模板化的低级序列化代码,我需要在编译时明确知道系统的字节顺序(因为模板专门基于系统的字节顺序).

现在我有一个带有一些平台定义的标题,但是我宁愿通过一些模板化测试(如static_assert或boost_if)来做关于字节序的断言.原因是我的代码需要编译并在许多专业供应商的各种机器上运行,并且可能是2008年不存在的设备,因此我无法猜测可能需要进入标题年份的内容在路上.而且由于代码库的预期寿命约为10年.所以我无法永远遵循代码.

希望这能使我的情况变得清晰.

那么有没有人知道可以确定字节序的编译时测试,而不依赖于供应商特定的定义?

c++ templates metaprogramming endianness

30
推荐指数
3
解决办法
7728
查看次数

如何在Python中找出方法的arity

我想找出Python中方法的优点(它接收的参数数量).现在我这样做:

def arity(obj, method):
  return getattr(obj.__class__, method).func_code.co_argcount - 1 # remove self

class Foo:
  def bar(self, bla):
    pass

arity(Foo(), "bar")   # => 1
Run Code Online (Sandbox Code Playgroud)

我希望能够做到这一点:

Foo().bar.arity()   # => 1
Run Code Online (Sandbox Code Playgroud)

更新:现在上面的函数失败了内置类型,对此的任何帮助也将受到赞赏:

 # Traceback (most recent call last):
 #   File "bla.py", line 10, in <module>
 #     print arity('foo', 'split')  # =>
 #   File "bla.py", line 3, in arity
 #     return getattr(obj.__class__, method).func_code.co_argcount - 1 # remove self
 # AttributeError: 'method_descriptor' object has no attribute 'func_co
Run Code Online (Sandbox Code Playgroud)

python metaprogramming

30
推荐指数
2
解决办法
7554
查看次数

模板元编程 - 我仍然没有得到它:(

我有一个问题......我不懂模板元编程.

问题是:我读了很多.但这对我来说没有多大意义:/

事实nr.1:模板元编程更快

template <int N>
struct Factorial 
{
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> 
{
    enum { value = 1 };
};

// Factorial<4>::value == 24
// Factorial<0>::value == 1
void foo()
{
    int x = Factorial<4>::value; // == 24
    int y = Factorial<0>::value; // == 1
}
Run Code Online (Sandbox Code Playgroud)

所以这个Metaprogram更快......因为Constant Literal.

但是:在现实世界中我们有不变的文字吗?

我用的大多数程序都会对用户输入作出反

事实nr.2:模板元编程可以实现更好的可维护性.

是啊.析因示例可以维护......但是当涉及到复杂的函数时,我和大多数其他C++程序员都无法读取函数.

调试选项很差(或者至少我不知道如何调试).

模板元编程在哪里有意义?

c++ templates metaprogramming

30
推荐指数
5
解决办法
1万
查看次数

30
推荐指数
2
解决办法
5365
查看次数

SFINAE检查继承的成员函数

使用SFINAE,我可以检测给定的类是否具有某个成员函数.但是如果我想测试继承的成员函数呢?

以下在VC8和GCC4中不起作用(即检测到A具有成员函数foo(),但不会B继承成员函数):

#include <iostream>

template<typename T, typename Sig>                                 
struct has_foo {                     
    template <typename U, U> struct type_check;
    template <typename V> static char (& chk(type_check<Sig, &V::foo>*))[1];
    template <typename  > static char (& chk(...))[2]; 
    static bool const value = (sizeof(chk<T>(0)) == 1);
};

struct A {
    void foo();
};

struct B : A {};

int main()
{
    using namespace std;
    cout << boolalpha << has_foo<A, void (A::*)()>::value << endl; // true
    cout << boolalpha …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming sfinae

30
推荐指数
4
解决办法
1万
查看次数

Ruby:如何将多个方法调用与"send"链接在一起

必须有一种内置的方式来做到这一点,对吧?

class Object
  def send_chain(arr)
    o=self
    arr.each{|a| o=o.send(a) }
    return o
  end
end
Run Code Online (Sandbox Code Playgroud)

ruby metaprogramming

30
推荐指数
3
解决办法
1万
查看次数

使用C++ 11可变参数模板在编译时快速排序

我刚刚通过使用C++ 11可变参数模板在编译时对其进行评估来实现快速排序算法.但是,当数据集太大时,我遇到性能问题.

#include <iostream>

using namespace std;

template<int... vs>
struct Seq
{}; 
template<int v1, int...vs>
struct Seq<v1, vs...>{
};


template<typename newT, typename srcT>
struct PushFront{
};
template<int vadded, int...vs>
struct PushFront<Seq<vadded>, Seq<vs...>>{
  typedef Seq<vadded, vs...> ResultType;
};

template<typename T>
struct PopFront{
};
template<int v1, int...vs>
struct PopFront<Seq<v1, vs...>>{
  typedef Seq<vs...> RemaindType;
  typedef Seq<v1>    ResultType;
};

template<typename T1, typename T2>
struct CatSeq{};
template<int...v, int...us>
struct CatSeq<Seq<v...>, Seq<us...>>{
  typedef Seq< v..., us... >  ResultType;
};


template<bool c, typename NewT, typename TrueClsT, typename …
Run Code Online (Sandbox Code Playgroud)

c++ metaprogramming quicksort variadic-templates c++11

30
推荐指数
2
解决办法
3126
查看次数

如何获取Ruby中已经"必需"的文件列表?

这纯粹是一个实验,但我想知道是否有可能require通过某种元编程在运行时获得'd gems 列表.例如,说我有:

require 'rubygems'
require 'sinatra'
require 'nokogiri'

# don't know what to do here
Run Code Online (Sandbox Code Playgroud)

如何在运行时打印出以下内容?

this app needs rubygems, sinatra, nokogiri
Run Code Online (Sandbox Code Playgroud)

ruby rubygems metaprogramming

30
推荐指数
2
解决办法
8728
查看次数

在Ruby中使用yield_method中的yield

是否可以在给定于define_method的块中生成yield关键字?简单的例子:

class Test
  define_method :test do |&b|
    puts b    # => #<Proc:...>
    yield
  end
end

Test.new.test {
  puts "Hi!"
}
Run Code Online (Sandbox Code Playgroud)

此代码在Ruby 1.8.7和1.9.0中都会产生以下错误:

test.rb:4:在`test'中:没有来自test.rb的块(LocalJumpError):8

奇怪的是b块变量!= nilblock_given?返回false.有意的Ruby行为是不是通过Proc对象识别块?

编辑:关于Beerlington的回答:b.call()不是我想要的.块变量仅用于指示实际给出块,并且在define_method中未检测到.

我需要用yield而不是用的原因block.call

我愿意为Ruby中定义新类的方式编写一些扩展,因此当我使用我的扩展时,你可以接受任何可以用纯Ruby编写的代码.

因此,不能考虑类似的语​​义,因为这会强制我的库的用户只使用一种正确的方法来传递一个块.这会破坏TIMTOWTDI规则,并且不会使我的库透明.

真实的例子

以下代码可以简化为上面的代码,因为my_def用途define_method:

require 'my_library'

class Test
  # client can write 'my_def' instead of 'def' since
  # my_library extends Class class
  my_def :test, "some parameter" do
    yield        # …
Run Code Online (Sandbox Code Playgroud)

ruby metaprogramming

29
推荐指数
2
解决办法
5709
查看次数